前言
死尸上线,继续学习。学习使我快乐。
题目链接
思路
看到第一眼想到的是KMP,第二眼是动态规划。没想到看走眼了。
这是一个典型的滑动窗口问题,就像这样。
下面我们来定义一下这个窗口的规则。
- 如果Right指向的指针与之前的字符没有重复,则将其右移
如图,就可以Right指针从b移动到c
- 如果Right 与之前的产生了重复,记录长度。将Left 依次右移直到不包含Right所指向的这个重复字符。如图,Left经过a,b,c 之后才会把前一个c排除在外
- 重复上面的步骤,如果发现Left 与 Right重合,则Right = Left+1,继续进行。
- 终止条件为Right 到达终点。
大致思路如此.下面看代码:
class Solution {
public:
int lengthOfLongestSubstring(string s) {
//首先设定一个map,用来存储在本次检测中出现的字符
int len = s.size();
int maxLen = 0;
int right = 1;
map<char,int> m;
for(int i = 0;i<len;i++){
m[s[i]] = 1; //我是Left,我行了
if(i == right) right = i+1;
while(right < len && m[s[right]] != 1){
m[s[right]] = 1; //别忘了标记已访问
right++;
}
maxLen = max(maxLen,right-i); //获得暂时最长
if(right == len) break;
m[s[i]] = 0;//我是Left,我凉了
}
return maxLen;
}
};
速度有点慢,空间复杂度ok
改进
很明显,上面第二步中依次右移将前一个c排除在外比较麻烦。我们可以在map中存储前一个的下标。让Left直接跳到应该的位置上。