leetcode之路(無重複字符的最長子串)

leetcode之路(無重複字符的最長子串)

題目:

給定一個字符串,請你找出其中不含有重複字符的 最長子串 的長度。

示例 1:
輸入: “abcabcbb”
輸出: 3
解釋: 因爲無重複字符的最長子串是 “abc”,所以其長度爲 3。

示例 2:
輸入: “bbbbb”
輸出: 1
解釋: 因爲無重複字符的最長子串是 “b”,所以其長度爲 1。

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

“實現一個功能如果需要10分鐘,思考的時間是7分鐘”
思考過程
這個題目的題意很清晰,暫時想到了兩種方法可以解答。方法一是不需要太多思考的暴力解題法,方法二是相對高級的方法滑動窗口法

方法一: 暴力解題法,解這個問題最簡單,最暴力的方法無非就是將給定字符串所有的符合題意(無重複字符)的字符串都列出來,取其中長度最大的,就是我們想要的答案。
在這裏插入圖片描述
上圖中省略號上一行應該是s[4]。

代碼大致如下

int lengthOfLongestSubstring(string s) {
 int ret=0;
        if(s=="")
        return 0;
        for(int i=0;i<s.size();i++){
             string temp;
            for(int j=i;j<s.size();j++){
            if(temp.find(s[j])==-1){
                if(temp.size()==0)
                temp.insert(0,1,s[j]);
                else
                temp.insert(temp.size()-1,1,s[j]);
                if(j==s.size()-1)
                	{ret=ret>=temp.size()?ret:temp.size();return ret;}
            }
            else{
                ret=ret>=temp.size()?ret:temp.size();
                if(j==s.size()-1) return ret;
                break;
            }
        }
        }
        return ret;}

提交結果:

√ Accepted
√ 987/987 cases passed (136 ms)
√ Your runtime beats 12.07 % of cpp submissions
√ Your memory usage beats 17.32 % of cpp submissions (21.3 MB)

在時間上僅擊敗了12.07%的人。
方法二: 現在我們來看方法二滑動窗口法,這個算法的思想其實和方法一基本一樣,但方法一中,當我們發現s[3]與s[0]重複是,我們拋棄了原有的字符串,創建了一個新的字符串又從s[1]開始,接着判斷s[2]是否與s[1]重複,但給過程我們在先前已經判斷過了。其實,當我們遇到重複字符時,我們可以依次的刪除我們字符串的第一個字符,直到與要加進去下一個字符沒有重複時,再把下一個字符加進去(語文水平有限,感覺自己都繞暈了,還是看圖吧,結合代碼應該跟容易理解些)。
在這裏插入圖片描述
方法二代碼

#include<iostream>
using namespace std;
#include<string>
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
       if(s.size()==0)
        return 0;
        int ret=1;
        string temp;								//子字符串
        temp.insert(0,1,s[0]);				//第一個字符肯定不重複,先放進去
        for(int index=1;index<s.size();index++){
            while(temp.find(s[index])!=-1){	//find()函數,未找到返回-1,說明temp中沒有s[index]字符
                temp.erase(temp.begin());     //當find()不等於-1時,依次刪去temp的第一個字符
            }
            temp.insert(temp.end(),s[index]);//find()函數=-1時,說明下一個字符插入沒有任何問題,把下一個字符插到temp的尾部。
            ret=ret>=temp.size()?ret:temp.size();//只有插入時,字符串長度有可能增大,故上面erase()函數後面無需判斷。
        }
        return ret;
    }
};

提交結果

√ Accepted
√ 987/987 cases passed (20 ms)
√ Your runtime beats 67.92 % of cpp submissions
√ Your memory usage beats 91.3 % of cpp submissions (9.1 MB)

方法一用了兩百多毫秒,方法二隻用了20ms.

發佈了17 篇原創文章 · 獲贊 27 · 訪問量 2632
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章