[刷題]無重複子串-滑動窗口問題

問題描述

最長無重複子串問題:
找到一個字符串中不含有重複字符的最長連續子串
如"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;  
}

相關題目

Leetcode
  1. 無重複字符的最長子串
  2. 串聯全部單詞的子串
  3. 最小覆蓋子串
  4. 至多包含兩個不一樣字符的最長子串
  5. 長度最小的子數組
  6. 滑動窗口最大值
  7. 字符串的排列
  8. 最小區間
  9. 最小窗口子序列
相關文章
相關標籤/搜索