力扣-3-无重复字符的最长字串
作者:互联网
做之前看题目的印象是“动态规划”,因为好像和以前做的“最大子数和”看起来有点像
查看标签有“滑动窗口”,这个见过听过,但是不知道具体是什么,但是有印象,计网里的拥塞控制也用到了“滑动窗口”的概念
感觉题目降低难度了,只是要求返回长度不是要求返回子串
有了计网“滑动窗口”的概念,我想是需要两个指针来表示窗口的,头指针表示窗口起始,尾指针表示窗口末尾。另外拿一个变量来记录窗口长度
感觉难点在于:
- 如何高效地判重
我想起了刚刚做的题,用set,如果把字串中的字符放到set中,然后用count函数来判断
那么,试试吧
int lengthOfLongestSubstring(string s) {
set<char> st;
int begin = 0,ret =0;
for(int end = begin;end<s.size();++end){
if(st.count(s[end])==0){
// set中没有该字符,说明没有重复
st.emplace(s[end]);// 放进去
}else{
// set中存在,有重复字符了
ret = max(ret,end-begin);
begin = end;// 刷新窗口
}
}
return ret;
}
第一版,三个示例通过了就迫不及待地提交,结果空字符就报错了
检查一遍健壮性
随手编了一个测试用例,发现一个问题:刷新窗口后set没清空
但还是不对,这是为什么?
问题应该出在最后遍历完成后没有再记录窗口长度,也就是说如果最长无重复子串在数组最后的情况
分析一下,遍历结束后,end指针应该在数组末尾,begin指针还在窗口开头
我把end改成类变量
有一个很复杂的问题,每次出现了重复字符不是把头指针与尾指针置通,而是头指针指向被重复字符的位置去,那我改map,刷新begin到被重复元素的后一个位置,然后这样又有了新问题,容器不能简单得清空了
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int ret = 0;
if(s==""){
return ret;
}
map<char,int> mp;
int begin = 0,end;
for(end = begin;end<s.size();++end){
if(mp.count(s[end])==1){
// set中存在,有重复字符了
int newLocation = mp.at(s[end])+1;
// 把begin到被重复字符之间的全踢掉
for(int i =begin;i<newLocation;++i){
mp.erase(s[i]);
}
begin = newLocation;// 刷新窗口
//放到被重复的字符位置去
}
// set中没有该字符,说明没有重复
mp.emplace(s[end],end);// 放进去
ret = max(ret,end-begin+1);
}
return ret;
}
};
这一版,能把目前的四个用例全部跑过
通过!
标签:字符,begin,end,int,力扣,字串,窗口,指针 来源: https://www.cnblogs.com/yaocy/p/16329023.html