題目:html
力扣原題連接:https://leetcode-cn.com/problems/longest-substring-without-repeating-characters/函數
給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。spa
示例 1:指針
輸入: "abcabcbb"code
輸出: 3 htm
解釋: 由於無重複字符的最長子串是 "abc",因此其長度爲 3。
示例 2:blog
輸入: "bbbbb"
輸出: 1
解釋: 由於無重複字符的最長子串是 "b",因此其長度爲 1。
示例 3:內存
輸入: "pwwkew"leetcode
輸出: 3字符串
解釋: 由於無重複字符的最長子串是 "wke",因此其長度爲 3。
請注意,你的答案必須是 子串 的長度,"pwke" 是一個子序列,不是子串。
解題:
方法一:利用vector容器
執行用時 :20 ms, 在全部 cpp 提交中擊敗了66.62%的用戶
內存消耗 :9.6 MB, 在全部 cpp 提交中擊敗了85.78%的用戶
方法二:雙指針滑動
執行用時 :4 ms, 在全部 cpp 提交中擊敗了99.47%的用戶
內存消耗 :9 MB, 在全部 cpp 提交中擊敗了95.92%的用戶
方法一:
對每個傳入字符串的字符與vector中的全部內容進行比較,無重複則將字符存入vector末尾,有重複則先更新不重複字符串最大值mlen,再將vector中的重複字符即其以前的內容刪掉,返回mlen。
vector的erase函數刪除向量中[first,last)中元素:iterator erase(iterator first,iterator last)。注意參數是iterator類型,不能用數值。應使用vector的一個函數:iterator begin()。返回向量頭指針,指向第一個元素。
vector的相關內容可參考:https://www.runoob.com/w3cnote/cpp-vector-container-analysis.html
class Solution { public: int lengthOfLongestSubstring(string s) { int n=s.length(); vector<char>str; int mlen=0; //掃描string s for(int i=0;i<n;i++){ char c = s[i]; //掃描vector str for(int m=str.size()-1;m>=0;m--){ if(c==str[m]){ //更新mlen if(mlen<str.size()) mlen = str. //刪除重複字符及其以前的字符。用vector的begin()函數控制刪除區間 str.erase(str.begin(),str.begin()+m+1); break; } } str.push_back(c); } if(mlen<str.size()) mlen=str.size(); return mlen; } };
方法二:
在s的字符數量大於等於2個的時候,用頭指針、尾指針指針分別指向s的開頭和其開頭+1,掃描兩指針之間的字符並與尾指針進行對比,根據對比狀況移動指針。
這期間只有兩種狀況,1:範圍[頭,尾)之間有跟尾字符重複的字符;2:沒有。
遇到狀況1時,更新最大長度mlen,頭指針指向重複字符的後一位置,尾指針後移一位,繼續掃描對比。
遇到狀況2時,頭指針不動,尾指針後移,繼續。
class Solution { public: int lengthOfLongestSubstring(string s) { int length=s.length(); //字符串長度爲0、1時直接返回數字,雙指針沒有地方指。 if(!length) return 0; if(length==1) return 1; //頭指針p,最大長度mlen至少爲1。 int p=0,mlen=1; //尾指針end for(int end=1;end<length;end++){ for(int aim=p;aim<end;aim++){ //狀況1 if(s[aim]==s[end]){ //更新頭指針p p=aim+1; //更新最大長度mlen if(mlen<(end-aim)) mlen=end-aim; break; } } //狀況2。要算上尾指針因此+1。 if(mlen<end-p+1) mlen=end-p+1; } return mlen; } };