面試題48:最長不含重復字符的子字符串(C++)


題目地址:https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/

題目描述

請從字符串中找出一個最長的不包含重復字符的子字符串,計算該最長子字符串的長度。

題目示例

示例 1:

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

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

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

解題思路

暴力法:將字符串中的每個字符存儲到字符串ss中,然后判斷字符串s中的每個字符是否出現在字符串ss中,即是否重復。

哈希表:使用哈希表記錄每個字符的下一個索引,然后向右移動右指針right來拓展滑動窗口的大小,並更新窗口的最大長度res。如果右指針right指向的元素s[right]重復,則將左指針left直接移動到窗口中重復元素的右側。

Set去重:使用set對字符串s去重,如果當前字符未出現在set中,則end右移,並把該字符插入set中,否則遇到重復元素,則從set中刪除。

雙指針:使用快慢指針,從左往右移動滑動窗口,判斷快指針right指向的元素是否出現在滑動窗口內,如果窗口內沒有該元素,則將該元素加入滑動窗口,同時更新窗口長度最大值,否則如果窗口存在該元素,即遇到重復元素,移動慢指針left,直到窗口中不包含該元素。

程序源碼

暴力

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size() == 0) return 0;
        int res = 0;
        for(int i = 0; i < s.size(); i++)
        {
            string ss = "";
            ss += s[i];
            for(int j = i + 1; j < s.size(); j++)
            {
                if(find(ss.begin(), ss.end(), s[j]) == ss.end()) ss += s[j];
                else break;
            }
            if(ss.size() > res) res = ss.size();
        }
        return res;
    }
};

哈希表

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size() == 0) return 0;
        unordered_map<char, int> mp;
        int res = 0;
        int left = 0, right = 0;
        while (right < s.size()) {
            if (mp.find(s[right]) != mp.end()) {
                left = max(left, mp[s[right]] + 1); //更新窗口起始位置left,例如abba,掃描到最后一個a時,left的原始位置為2
            }
            mp[s[right]] = right;
            right++;
            res = max(right - left, res);
        }
        return res;
    }
};

Set去重

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size() == 0) return 0;
        int res = 0;
        int begin = 0, end = 0;
        set<char> count_ch;
        for(int i = 0; i < s.size(); i++)
        {
            while(count_ch.count(s[i]) != 0)
            {
                count_ch.erase(s[begin++]);
            }
            count_ch.insert(s[i]);
            end++;
            res = max(end - begin, res);
        }
        return res;
    }
};

雙指針

class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        if(s.size() == 0) return 0;
        int res = 0;
        int right = 0;
        for(int i = 0; i < s.size(); i++)
        {
            int left = right;
            while(left < i)
            {
                if(s[left] == s[i]) right = left + 1;
                left++;
            }
            res = max(i - right + 1, res);
        }
        return res;
    }
};

參考文章

https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/c-hua-dong-chuang-kou-shuang-zhi-zhen-ha-xi-biao-j/

https://leetcode-cn.com/problems/zui-chang-bu-han-zhong-fu-zi-fu-de-zi-zi-fu-chuan-lcof/solution/lioney-cqiao-yong-biao-ji-wei-by-lioney/


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM