用滑動窗口來解決最長無重複子串問題

題目描述

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

示例1:數組

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

示例2:學習

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

示例3:優化

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

解法1:滑動窗口

滑動窗口是解決字符串和數組類問題的一個重要工具。就本地而言,咱們使用以下解題思路:code

  1. 假設輸入字符串爲:pwwkew
  2. 初始化map, key爲字符,value爲該字符在輸入字符串中的位置。
  3. 初始化i=0,j=0。
  4. 查看j所對應的元素newJValue是否否在與map中:
    1. 若是它在map中,則從map中刪除i所指向的元素,並將i向右滑動,繼續執行4。
    2. 若是它不在map中,則將其插入到map,並將j向右滑動,繼續執行4。並起來當前最大值m。
class Solution {
public:
    int lengthOfLongestSubstring(string str) {
        int i = 0;
        int j = 0;
        int m = 0;
        int size = (int)str.size();
        
        map<char, int> tmap;
        while (i<size && j<size) {
            if (tmap.find(str[j]) == tmap.end()) {
                tmap.insert(pair<char, int>(str[j], j));
                j++;
                m = max(m, j-i);
            } else {
                tmap.erase(tmap.find(str[i]));
                i++;
            }
        }
        return m;
    }
};
複製代碼

優化代碼cdn

這裏的優化思路是:當i須要向右滑動的時候不須要一次一次的滑動,而是直接跳到新的重複元素。字符串

舉例來講,對於測試用例:pwwkew來說。

當j=2,i=0是,map中已經有了pw了,對於j=2的w在map中已經存在w,因此此時須要將i右滑兩次,只是咱們能夠直接將i跳到2,而不用一步一步的滑動。具體代碼以下:

int lengthOfLongestSubstring(string str) {
        int i = 0;
        int j = 0;
        int m = 0;
        int size = (int)str.size();
        
        map<char, int> tmap;
        while (j<size) {
            if (tmap.find(str[j]) != tmap.end()) {
                i = max(tmap.find(str[j])->second, i);
            }
            m = max(m, j-i+1);
            tmap[str[j]] = j+1;
            j++;
        }
        return m;
    }
複製代碼

交流學習

交流學習
相關文章
相關標籤/搜索