題目地址: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; } };
參考文章