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

題目鏈接

Problem Description

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

示例 1:

輸入: "abcabcbb"
輸出: 3 
解釋: 因爲無重複字符的最長子串是 "abc",所以其長度爲 3。
示例 2:

輸入: "bbbbb"
輸出: 1
解釋: 因爲無重複字符的最長子串是 "b",所以其長度爲 1。
示例 3:

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

思路

這道題如果用暴力的話時間複雜度是O(n^2),所以我們需要想辦法進行優化,怎麼優化呢?

因爲暴力中有很多操作是多餘的,比如遇到相同的字符時就沒必要再執行下去了,因此我們就需要從這個地方下手,

利用雙指針滑動窗口,維護窗口中不允許有重複的字符出現,一旦有重複字符,就更新窗口,讓窗口的begin指針前移,知道窗口中沒有重複字符爲止,

下面以abcabcbb作爲示例進行演示:(期間還需要一個數組flag,用於記錄某個字符是否出現過)

最開始的時候begin指針和i指針都在字符串的起始位置

然後i指針不斷前移,直到走到這裏,發現flag[a]爲1,a出現過,此時就需要更新begin指針

將begin指針移動到<begin,i>這個窗口中沒有重複字符,然後 i 繼續++,需要更新begin指針時,繼續更新窗口

下面結合代碼再捋一遍

代碼

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.length() < 2){
            return s.length();
        }
        int flag[128] = {0};//用於存滑動窗口內字符出現的次數,以便更新窗口
        int begin = 0;//雙指針滑動窗口
        int ans = 0;
        for(int i = 0; i < s.length(); i++){
            if(flag[s[i]] >= 1){  //說明字符s[i]出現過,此時需要更新滑動窗口的begin指針
                while(flag[s[i]]){  //begin更新到窗口內沒有重複字符的地方
                    flag[s[begin]]--;
                    begin++;
                }
            }
            flag[s[i]]++;//標記字符
            ans = max(ans,i-begin+1);
        }
        return ans;
    }
};

 

 

 

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章