最长无重复子串问题:
找到一个字符串中不含有重复字符的最长连续子串如"pwwkew"的解为"wke"
这个问题难点在于如何保证当前的子串是无重复的,
换句话说,来了一个重复的字符该怎么处理?
1.咱们确定不容许子串中有重复的字符,那么咱们用一个窗口维护一个无重复字符的子串,
2.若是新字符不是重复字符,直接将右边界滑至该字符。
3.当来了一个重复字符时,思考窗口怎么移动。截至该字符以前的最长子串咱们已经求得,因此咱们能够放心的滑动左边界,丢弃一些元素直至该字符再也不是重复字符,同时,咱们把右边界滑到当前字符。经过这样作,咱们能保证咱们在日后遍历的过程当中依然维护了一个无重复的子串。数组
如"abca"到第二个'a'时,窗口左边界滑到'b',右边界滑到'a'
code
4.每次窗口调整结束以后,计算当前子串的长度。字符串
模板代码以下,有一些细节须要注意get
public int lengthOfLongestSubstring(String s) { // map记录每种字符最新的下标 HashMap<Character, Integer> map = new HashMap<>(); int start = 0; // 当前子串的起始位置 int maxlen = 0; for(int i=0;i<s.length();i++){ char c = s.charAt(i); // 若是map中包含该字符,可能须要滑动窗口 // 为何说“可能”: 这个字符可能在以前的子串中出现过,而且滑动窗口已经滑过该字符 // 如 "bacab" 当右边界到达第二个'a'时, start的位置为上一个'a'的位置+1 即为'c'的位置 // 但此时右边界到底'b'时,虽然map中包含'b',但咱们不能把左边界移到上一个'b'的位置+1, // 由于窗口已经划过了那个位置,因此咱们须要取max(左边界, 上一个该字符的位置+1) if(map.containsKey(c)){ start = Math.max(start,map.get(c)+1); } // 更新字符的位置 map.put(c, i); maxlen = Math.max(maxlen,i-start+1); } return maxlen; }