Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

java find the longest non-repeating substring- getting weird result

Tags:

java

I am doing one classic leet code problem: finding the longest non-repeating substring in a string. Though there are many similar problems on stack overflow. I scratched my head for hours couldn't know why my code produce this weird result. hoping that someone could tell me why my

I am doing it in Java

    public static void main( String[] args )
    {
        String s= "wwhoamiUrektxineabcdefghijklmno";
        longestNonRepeatStr(s);     
    }

    public static void longestNonRepeatStr(String tstring) {
        String str="";
        String compare="";
        List<String> list= new ArrayList<String>();
        int biggest =0;

        //find the nonrepeating string in each loop and add to list str
       for (int i=0; i<tstring.length(); i++) { 
        for (int j=i; j<tstring.length()-1; j++) {
            str+= tstring.charAt(j);
            compare= Character.toString(tstring.charAt(j+1));
            if (str.contains(compare)){
                list.add(str);
                str="";
                break;
            }
        }
    }

    //find the longest nonrepeating string in the list
       for (int i=0; i<list.size(); i++) {
        if (list.get(biggest).length()< list.get(i).length()) {
        biggest=i;
        }
    }

       System.out.println(list);    
       System.out.println(list.get(biggest));           
    }

For input string

"wwhoamiUrektxineabcdefghijklmno"

output is

"abcdefghijklmnb" 

but it is wrong, the last letter should be "o"

like image 988
Ken Avatar asked Oct 07 '19 07:10

Ken


People also ask

How do you find the longest unique substring in Java?

Run a loop from i = 0 till N – 1 and consider a visited array. Run a nested loop from j = i + 1 to N – 1 and check whether the current character S[j] has already been visited. If true, break from the loop and consider the next window. Else, mark the current character as visited and maximize the length as j – i + 1.

How do you find the longest repeated substring in a string?

Suppose we have a string S, we have to find the length of the longest repeating substring(s). We will return 0 if no repeating substring is present. So if the string is like “abbaba”, then the output will be 2. As the longest repeating substring is “ab” or “ba”.


1 Answers

You have several issues (see comments where I corrected the code):

public static void longestNonRepeatStr(String tstring) {
  String str="";
  String compare="";
  List<String> list= new ArrayList<String>();
  int biggest =0;

  for (int i=0; i<tstring.length(); i++) { 
    str = ""; // you must clear the current String before each iteration of the inner loop
    for (int j=i; j<tstring.length(); j++) { // here you were skipping the last character
      str+= tstring.charAt(j);
      // I improved the following condition
      if (j+1 < tstring.length() && str.contains(Character.toString(tstring.charAt(j+1)))){
        list.add(str);
        str="";
        break;
      }
    }
    if (str.length() > 0) { // if you finish the inner loop without breaking, you should
                            // add the current String to the List
      list.add(str);
    }
  }

  for (int i=0; i<list.size(); i++) {
    if (list.get(biggest).length()< list.get(i).length()) {
      biggest=i;
    }
  }

  System.out.println(list);    
  System.out.println(list.get(biggest));           
}

Or, as an alternative, you can add the current String to the List in the last iteration of the inner loop:

public static void longestNonRepeatStr(String tstring) {
  String str="";
  String compare="";
  List<String> list= new ArrayList<String>();
  int biggest =0;

  for (int i=0; i<tstring.length(); i++) { 
    str = "";
    for (int j=i; j<tstring.length(); j++) {
      str+= tstring.charAt(j);
      if (j+1 >= tstring.length() || str.contains(Character.toString(tstring.charAt(j+1)))){
        list.add(str);
        str="";
        break;
      }
    }
  }

  for (int i=0; i<list.size(); i++) {
    if (list.get(biggest).length()< list.get(i).length()) {
      biggest=i;
    }
  }

  System.out.println(list);    
  System.out.println(list.get(biggest));           
}

Further explanation of how you got the output "abcdefghijklmnb":

When i==16, your inner loop builds the String "abcdefghijklmn". Then it skips the "o", since you ended that loop prematurely (due to j<tstring.length()-1). This String is not yet added to the List, since you haven't detected a repeating character. Now when i==17, you append "b" to str and get "abcdefghijklmnb". Now you check if the next character "c" already appears in str, which is true, so you add "abcdefghijklmnb" to your List.

like image 87
Eran Avatar answered Sep 21 '22 21:09

Eran