C++雙指針滑動和利用Vector實現無重複字符的最長子串—力扣算法

題目: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;
    }
};
相關文章
相關標籤/搜索