【LeetCode】3. 無重複字符的最長子串

3. 無重複字符的最長子串

知識點:字符串,滑動窗口code

題目描述

給定一個字符串 s ,請你找出其中不含有重複字符的 最長子串 的長度。索引

示例
輸入: s = "abcabcbb"
輸出: 3 
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3。

輸入: s = "bbbbb"
輸出: 1
解釋: 由於無重複字符的最長子串是 "b",因此其長度爲 1。

輸入: s = "pwwkew"
輸出: 3
解釋: 由於無重複字符的最長子串是 "wke",因此其長度爲 3。
     請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。

輸入: s = ""
輸出: 0

解法一:滑動窗口

滑動窗口其實就是一種隊列;隊列

對於本題,依次入隊,當發現這個隊列中含有重複元素的時候,把重複元素以前的值所有移除。好比 a b c a b;到第二個a的時候將a出隊;
若是不用隊怎麼實現,其實就是維持了一個滑動着的窗口,右邊界依次在遍歷,左邊界也在移動,並且注意左邊界必定不會回退的。當遍歷到的元素出現過了的時候,要把左邊界移動;leetcode

其次不能有重複元素 -- > 哈希表;字符串

用哈希表存儲每一個字符和字符出現的索引,當出現重複字符的時候,移動左邊界;注意兩種狀況:get

  • a b c a; 第二個a的時候要把左邊界移動到a的下一個處,至關於a出隊;
  • a b b a; 到達第2個b的時候由於以前含有b了,因此map.get(b)+1,也就是左邊界到了2,可是到下一個a的時候,若是還用一樣的,那left = map.get(a)+1 = 1,就又回去了,因此應該取二者中的大值;至關於a b出隊;出去的可千萬別再進來了;滑動窗口的左右邊界是永遠不會回退的。

一句話:沒有觸發條件,右窗口一直移動;達到觸發條件,左窗口移動,促使條件再次不知足;,在這個題裏,條件就是窗口內是否有重複字符;string

class Solution {
    public int lengthOfLongestSubstring(String s) {
        int len = s.length();
        int maxLen = 0;
        int left = 0;
        Map<Character, Integer> map = new HashMap<>(); //爲了檢查重複,存儲字符和其出現的索引;
        for(int i = 0; i < len; i++){
            if(map.containsKey(s.charAt(i))){
                left = Math.max(left, map.get(s.charAt(i))+1); //左窗口移動;左右邊界永不回頭;
            }
            map.put(s.charAt(i), i);
            maxLen = Math.max(maxLen, i-left+1);
        }
        return maxLen;
    }
}

相關連接

無重複字符的最長子串it

相關文章
相關標籤/搜索