leetcode

Longest Substring Without Repeating Characters

Given a string, find the length of the longest substring without repeating characters. For example, the longest substring without repeating letters for "abcabcbb" is "abc", which the length is 3. For "bbbbb" the longest substring is "b", with the length of 1.

The idea is to scan the string from left to right, keep track of the maximum length Non-Repeating Character Substring (NRCS) seen so far. Let the maximum length be max_len.

When we traverse the string, we also keep track of length of the current NRCS using cur_len variable. For every new character, we look for it in already processed part of the string (A temp array called visited[] is used for this purpose). If it is not present, then we increase the cur_len by 1. If present, then there are two cases:

a) The previous instance of character is not part of current NRCS (The NRCS which is under process). In this case, we need to simply increase cur_len by 1.

b) If the previous instance is part of the current NRCS, then our current NRCS changes. It becomes the substring staring from the next character of previous instance to currently scanned character. We also need to compare cur_len and max_len, before changing current NRCS (or changing cur_len).

    "abcdabd" -> first iteration "abcd", length=4.
               -> then we see the fifth char 'a' again, a is part of the processing string, because previousIndex+length == currentIndex = 4, so the current length = 4
               -> then the next char is b, it is also visited before, so the current length is still 4.

    "abcdaebd" -> first iteration "abcd", length=4.
                -> then we see the fifth char 'a' again, a is part of the processing string, because previousIndex+length == currentIndex = 4, so the current length = 4
                -> then the next char is e, it is not visited before, so the current length is set to 5.
public int lengthOfLongestSubstring(String s) {
        if (s==null||s.length()==0) {
            return 0;
        }

        //ASCII char set is size of 256
        int[] visited = new int[256];
        Arrays.fill(visited, -1);

        int maxLength = 1;
        int currLength = 1;
        visited[s.charAt(0)] = 0;

        for (int i=1; i<s.length(); i++) {
            char currChar = s.charAt(i);
            int previousIndex = visited[currChar];

            //if the char is not met or is not part of the current processing string
            if (previousIndex==-1||previousIndex+currLength<i) {
                currLength = currLength+1;
            } else {               
                currLength = i-previousIndex;
            }

            maxLength = Math.max(currLength, maxLength);
            visited[currChar] = i;
        }
        return maxLength;
    }