1. 程式人生 > >LeetCode #3 Longest Substring Without Repeating Characters

LeetCode #3 Longest Substring Without Repeating Characters

rep lee 子序列 continue uno rip 更新 存在 fin

Description


Given a string, find the length of the longest substring without repeating characters.

題意


給定一個字符串,求出不帶重復字符的最長子串的長度。

Example


Given "abcabcbb", the answer is "abc", which the length is 3.

Given "bbbbb", the answer is "b", with the length of 1.

Given "pwwkew", the answer is "wke", with the length of 3

. Note that the answer must be a substring, "pwke" is a subsequence and not a substring.

思路


  這道題涉及查找,肯定是使用哈希表是最快的。假設Key 是字符串中的字符,Value 是長度,每次掃描時令鍵與當前掃描到的字符匹配,如果重復了就不加入 Map,最後輸出 longth。但是這樣的辦法有問題,因為它求出來的是子序列而不是子串,樣例3通不過,顯示輸出的是4。

//Note:This is Wrong Answer !!!
#include<unordered_map>
using std::unordered_map;
class Solution { public: int lengthOfLongestSubstring(string s) { unordered_map<char,int> um; int i; int n = s.size(); int longth = 0; for (i = 0; i < n; ++i) { if (um.find(s[i]) != um.end()) { continue; }
else{ um[s[i]] = ++longth; } } um.clear(); return longth; } };

  

  隨後,我再思考了一遍題目,發現其實這題可以想象成一個隊列,每次入隊時都需要查看隊裏有沒有重復的字符,若有則將重復的字符及其之前的字符給刪去,這樣就可以保證隊內沒有重復的字符了。那麽問題就來了,如何去模擬這樣一個隊列?

  我們可以用1個 set 和 兩個哨兵 i j 去模擬一個隊列。set (集合)是一個 key 與 value 必須相等的數據結構,用它的原因是它可以用紅黑樹或哈希表實現,查找效率高一些。哨兵 i 表示子串左端,哨兵 j 表示子串右端,每一輪掃描都在 set 的鍵中查找 s[j] 是否存在,若不存在則在 set 中增加元素 s[j] 且 j++,若存在則在集合 set 中刪去元素 s[i] 且 i++,這樣就實現了一個隊列的操作,一段出,一段入。

  如何求最長子串呢?在每一輪中實時比較子串長度並更新記錄 res即可。

//Runtime: 46 ms
#include<set> #include<algorithm> using std::set; using std::max; class Solution { public: int lengthOfLongestSubstring(string s) { set<char> mySet; int res = 0, temp = 0; int i = 0,j = 0; int n = s.size(); while (j < s.size()) { if (mySet.find(s[j]) != mySet.end()) { mySet.erase(s[i]); ++i; } else { mySet.insert(s[j]); ++j; } temp = mySet.size(); res = max(res, temp); } mySet.clear(); return res; } };

  感覺我的方法還是有些慢,如果有更好的辦法歡迎討論。

  

LeetCode #3 Longest Substring Without Repeating Characters