3. 無重複字符的最長子串(滑動窗口)

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

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

示例 3:

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

思路:如果遍歷所有子串並檢查子串中字符是否重複,時間複雜度爲O(n3),可以維護一個窗口,窗口中所有的字符都不重複,不斷擴充窗口右端,當擴充後的窗口不滿足條件,就收縮窗口左端。

採用哈希表來查找元素是否出現過,查重操作就可以在O(1)時間內完成。

時間複雜度爲O(n),n爲字符串的長度。

class Solution{
public:
    int lengthOfLongestSubstring(string s){
        //s[start,end) 前面包含 後面不包含
        int start(0), end(0), length(0), result(0);
        int sSize = int(s.size());
        //hash[c] = 1表示窗口內有字符c,爲0表示窗口內沒有c
        unordered_map<char, int> hash;
        while (end < sSize){
            char tmpChar = s[end];
            //當窗口右端end可以擴展
            if (hash.find(tmpChar) == hash.end() || hash[tmpChar] == 0){
                hash[tmpChar] ++;
                end++;
                //窗口擴展,嘗試更新答案
                result = max(result, end - start);
            }else{
                //收縮窗口左端
                hash[s[start]] --;
                start++;
            }
        }
        return result;
    }
};

優化:上述哈希表映射的只是字符c是否在窗口內。考慮當我們擴充窗口右部,窗口內的字符串不滿足條件必然是窗口右部剛剛新加入的字符,如果我們把hash表的值設爲字符c出現的下標,那麼當條件不滿足的時候,只需要將窗口的左部改變爲hash[c]+1,即跳過遍歷前面所有含c的子串(因爲窗口已經有一個字符c了)。

時間複雜度:O(n)

優化後的滑動窗口

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