引言
今天是leetcode的第四天,昨天也就是第三天,我刷的是1357题,感觉它考的是更多对类的掌握,没有啥技术难度,也就没啥收获了,也没必要写博客来记录了
今天刷的是leetcode的第三题,无重复字符的最长子串,我可以说我算法功底真是有点差,这道题花了我好长时间去调试。而且我满脑子都是O( n 2 n^2 n2)的算法,如果只是单纯的两重循环O( n 2 n^2 n2),那么这必会超时。所以我做的更多的对O( n 2 n^2 n2)的优化
原代码
这代码是过了的,不过对比于其他nb的O(n)算法,可以说是垫底的了。
class Solution {
public:
bool isRepeat(string s,int start,int end){
map<char,int>a;
for(int i = start;i<=end;i++){
if(++a[s[i]]>1)return true;
}
return false;
}
int findRepeat(string s,int start){
for(int i = start+1;i<s.length();i++){
if(s[i] == s[start]) return i;
}
return 0;
}
int lengthOfLongestSubstring(string s) {
int strlen = s.length();
int l = 0;
for(int i = 0;i<strlen-1;i++){
int j = findRepeat(s,i);
if(j-i == 1)continue;
if(j == 0) j = strlen - 1;
else j--;
while(j-i+1>l&&j>i){
if(!isRepeat(s,i,j))l = max(l,j-i+1);
j--;
}
}
return strlen == 0 ? 0:max(l,1);
}
};
我这里所说的优化便是 对于每一个开始位置,都从后面的子串找到一个和它相同字符直到字符串的结尾。避免第二次循环不必要的循环次数。
这里还有一个优化点,优化了这里我才能过的, 就是循环前先判断j和i之间的距离是否大于当前,如果小于,那么这个循环就没有什么意义了,就结束循环。
优化代码
这个代码是看了大佬的提解,理解意思后做出来的。利用的移动窗口的思想
class Solution {
public:
int lengthOfLongestSubstring(string s) {
map<char,int>dir;
int start = 0;
int ans = 0;
for(int i = 0;i<s.length();i++){
if(dir.count(s[i])){
start = max(start,dir[s[i]]+1);
}
dir[s[i]] = i;
ans = max(ans,i-start+1);
}
return ans;
}
};
收获
当然是移动窗口这个思想啦
还有的话就是判断map是否有某个key
dir.count(s[i])