javahashlongest-substring

Longest Substring Without Repeating Characters: Wrong answer


I have sent hours trying to find out the reason why the method returns a wrong answer for this particular test case: "qrsvbspk". The method returns 6 instead of 5. I cannot figure out what is wrong. Plz help!

Here's my approach:

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int i = 0;
        int max_count = -1;
        int count = 0;
        
          if(s.length() == 0)
              return 0;
        
        HashSet<Character> set = new HashSet();
        
        int k = 0;
        while(k < s.length()){
            i = k;
            while(i < s.length() && !set.contains(s.charAt(i))){
                count++;
                set.add(s.charAt(i++));
            }
            if(count >= max_count){
                max_count = count;
                set.clear();
                count = 0;
            } 
                k++;
        }
        return max_count;
    }
}

Solution

  • Your approach is not correct because you only clear the Set and reset the count if a longer substring is found, when you should be doing that on each iteration of the outer loop.

    You can use a two-pointers approach for increased efficiency. As the left pointer moves from 0 the the 1 less than the length of the String, we keep increasing the right pointer until we reach a character that is already in the Set. After that, the length of the current substring is right - left and we remove the character at the left index from the Set. Since both pointers can be increased at most N times (where N is the length of the String), this approach runs in O(N).

    public int lengthOfLongestSubstring(String s) {
        int max_count = 0;
        HashSet<Character> set = new HashSet();
        int left = 0, right = 0;
        while(left < s.length()){
            while(right < s.length() && set.add(s.charAt(right))){
                ++right;
            }
            max_count = Math.max(max_count, right - left);
            set.remove(s.charAt(left++));
        }
        return max_count;
    }