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
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章