【leetCode】之 Longest Substring Without Repeating Characters

一道挣扎了两天的题[罪过.jpg]

从内存超限到时间超限再到答案错误到最后的答案正确【当然期间看了下别人的代码与提示】,自己用了贪心,解决了时间超限问题,最后再提交的过程中弥补了自己算法的不足~

题目:

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

Example 1:

Input: "abcabcbb"
Output: 3 
Explanation: The answer is "abc", with the length of 3. 

Example 2:

Input: "bbbbb"
Output: 1
Explanation: The answer is "b", with the length of 1.

Example 3:

Input: "pwwkew"
Output: 3
Explanation: 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.

题目大意就是求没有重复字符串的最长子串。

开始的时间超限的思路:先用双层for循环求子串,在双层循环中调用判断子串中是否有重复字符的函数,当然最后悲剧了,虽然我让循环次数尽可能的少了,但。。。。

所以开始改尽自己的方法,开始的时候认为是自己调用的函数不够精简,又去学习了下C++的容器有关的知识,用map对象又写了一个求字符串中是否有重复字符的函数,依然未能成功。最后琢磨了下别人的代码,知道有简单的方法,但是自己不太理解,后来找了下别人的思路,知道他用了滑动窗口的理念,所以又自己重新思考了下,以至最后解出此题。 

思路题目要求的是连续的无重复的最大子串长度,所以可以假设一个窗口初始的大小为0,在遍历题目所给字符串的时候,若此字符在你所记录的起始位置到此时遍历的位置中没有重复出现,就扩大窗口长度,每次更新max值。若出现过,则从上次出现过的位置的下一位开始重新求无重复的子串长度,并计数更新max值。

现在借助一些变量来理解我的思想。

        int first = 0 ;   //记录你现在子串的起始位置(并不一定表示最长子串的起始位置)
        int max = 1 ;  //最后所求的子串长度最大值(前面为0的情况我直接返回了,所以这里设为1)
        int count = 0 ;  //记录从first开始的无重复字符的子串可延伸的长度,即现在窗口的最大长度
        int score[300] ;  //score[k] = x  表示为  score[s[i]] = 上一次出现字符s[i]的位置x,用此数组来查看该字符是否重复出现。初值为-1(因为记录字符出现过的位置,所以取任意负值均可)

1、遍历string s[i] ,起始的时候first在下标0处,即从0开始让窗口尽可能的大,若访问一个字符s[i]时,上一次出现过的位置score[s[i]] == -1(即从first开始未出现过)则更新s[i]所在的位置,并且长度+1,即count++,并让max=max(max,count)

2、上一步解决从first开始后未出现过字符的情况,那接下来考虑的是:当遍历到s[i]时,s[i]在之前已经出现过,即

score[s[i]]!=-1 ,那么此时 first就要从上一次出现s[i]的下一个位置开始,并且count要重新计数,当然first变更之后,变更前后之间的字符位置要归为-1,以便后面重新计数,查找下一个子串。并且i是每次+1的,此次因为s[i]出现过,first滑倒了上次s[i]出现位置的下一位,也就是score[s[i]]现在为-1,所以此时的做法是将i-1,让其更新s[i]的位置。

其实重要的是几个初始变量的意义,剩下的可以看代码理解,此题主线是字符串连续不跳跃,可用贪心

附C++代码:

​
class Solution {
public:
    int lengthOfLongestSubstring(string s) {
        
        if(s.length() == 0) return 0 ;
        
        //贪心;滑动窗口,以至窗口长度最大;
        int first = 0 ;
        int max = 1 ;
        int count = 0 ;
        int score[300] ;
        
        for(int i = 0 ; i < 300 ; i++)  //score[k] = x ==> score[s[i]] = 上一次出现的位置x
            score[i] = -1 ;
        
        for( int i = 0 ; i < s.length() ; i++){
            
            if(score[s[i]] == -1){
                score[s[i]] = i;
                count ++;
                if(count > max)
                    max = count ;
            }
            else{
                
                for( ; first <= score[s[i]] ; first++)
                    score[s[first]] = -1 ;
                
                count = i - first ;
                i-- ; //由于没走if,此时的s[i]位置没被更新,所以-1,重新赋值
            }  
        }
        return max ;
    }
};

​

 

Python网络爬虫与推荐算法新闻推荐平台:网络爬虫:通过Python实现新浪新闻的爬取,可爬取新闻页面上的标题、文本、图片、视频链接(保留排版) 推荐算法:权重衰减+标签推荐+区域推荐+热点推荐.zip项目工程资源经过严格测试可直接运行成功且功能正常的情况才上传,可轻松复刻,拿到资料包后可轻松复现出一样的项目,本人系统开发经验充足(全领域),有任何使用问题欢迎随时与我联系,我会及时为您解惑,提供帮助。 【资源内容】:包含完整源码+工程文件+说明(如有)等。答辩评审平均分达到96分,放心下载使用!可轻松复现,设计报告也可借鉴此项目,该资源内项目代码都经过测试运行成功,功能ok的情况下才上传的。 【提供帮助】:有任何使用问题欢迎随时与我联系,我会及时解答解惑,提供帮助 【附带帮助】:若还需要相关开发工具、学习资料等,我会提供帮助,提供资料,鼓励学习进步 【项目价值】:可用在相关项目设计中,皆可应用在项目、毕业设计、课程设计、期末/期中/大作业、工程实训、大创等学科竞赛比赛、初期项目立项、学习/练手等方面,可借鉴此优质项目实现复刻,设计报告也可借鉴此项目,也可基于此项目来扩展开发出更多功能 下载后请首先打开README文件(如有),项目工程可直接复现复刻,如果基础还行,也可在此程序基础上进行修改,以实现其它功能。供开源学习/技术交流/学习参考,勿用于商业用途。质量优质,放心下载使用。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值