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.

思路:用head与tail维护一个窗口,HashSet来记录窗口中的字符。tail向后遍历,当遍历到重复的字符时停下,然后移动head,让head跳过与tailChar重复的那个字符,即从左侧缩小窗口,跳过与tailChar冲突的那个字符,使窗口中不再包含重复字符。(因为substring得是连续的字符串,故单纯向右移动head即可)此时head成为新窗口的左边界,然后再移动tail看新窗口的Length能否超过上个窗口

//因为head与tail都只向右移动,对每个元素最多遍历两次。而hashset使contains/add/remove具有常数时间复杂度
//故算法复杂度为O(2n)=O(n),空间复杂度为O(size of set)
public class Solution {
    public int lengthOfLongestSubstring(String s) {
        
        if(s==null || s.length()==0){
            return 0;
        }
        
        HashSet<Character> set = new HashSet<Character>();  //窗口子串中的字符集合
        int head = 0; 
        int tail = 0;                                       //用head与tail维护一个窗口
        int maxLength = 0;
        
        for(tail=0; tail<s.length(); tail++){
            char tailChar = s.charAt(tail);
            if(!set.contains(tailChar)){         //tailChar与窗口子串的字符不重复,直接加入set然后下次遍历即可
                set.add(tailChar);
            }else{                               //如果tailChar在窗口子串中已经有了,就得停下来
            
                if(tail-head > maxLength){       //更新maxLength
                    maxLength = tail-head;
                }
                
                while(s.charAt(head) != tailChar){   //移动head,使head-tail段的窗口中不再有重复字符
                    set.remove(s.charAt(head));      //例abcabcd,当运行到head=0,tail=3时,不执行此循环,仅head++
                    head++;                          //而若abccbcd,运行到head=0,tail=3时,把head+2,再执行head++,
                }
                
                head++;                              //跳过冲突字符的最后一跃
            }
        }
        
        //可能窗口位于s的末尾,则循环终止时,maxLength是前面各个窗口中最长的,不包含最后的这个窗口
        return Math.max(maxLength, tail-head);
    }
}
原文地址:https://www.cnblogs.com/dosmile/p/6444420.html