昨天爬香山可真是翠绿啊😭,没见着漫山的红叶倒是把腿爬废了。周末两天就快过了,临时兴起继续打打LeetCode的卡吧
今天第三题:无重复字符的最长子串
今天开始会将完整的题目贴上来,完整题目如下:
看着这个题目,脑子里隐隐感觉大二上算法课好像有个算法就是解决这个问题的,但目前也就想起这么点东西了。打卡开始........(希望多刷刷题能帮我多想起来一点算法知识)
1、方法一:自己脑子里想的,不涉及任何算法知识的解法
看到题目的第一时间,我的脑子里想到的是,在遍历字符串的过程中计算从每一位(用start标识)开始不重复的最长子串,在这个过程中不断对比更新最长子串的长度。时间复杂度O(n2)。
在编码测试的过程中发现了一个容易踩坑的小点:当出现连续的相同字符时,需要将遍历的字符串下标复位到start,否则会出现跳过相同字符,导致结果出错。
代码用java编程,完整代码如下:
class Solution {
public int lengthOfLongestSubstring(String s) {
int l = s.length();
int max = 0;
int start = 0;
boolean flag = false;
for(int i=0; i<l; i++){
flag = false;
char a = s.charAt(i);
for(int j = start; j<i; j++){
char b = s.charAt(j);
if(a==b){
flag = true;
break;
}
}
if(flag){ //出现重复
i=start;
start+=1;
}else{ //未出现重复
int len = i-start+1;
max = max>len?max:len;
}
}
return max;
}
}
2、方法2:解答区观摩大佬答案(学算法)
滑动窗口:看完官方的解答后,总结出以下几个重点思路
1)首先是一个算法思路:当已经确定i到j无重复字符时,而i与j+1重复,那么其实已知 i+1 到j是无重复的,就这一点足够将时间复杂度从O(n2)降低到O(n)了。
2)之后是一个编程思路:看到“不重复”三个字应该联想到集合(set)数据结构的,引入集合后,编码难度大幅度下降啊。
依上述思路完整代码实现如下(使用C++):
class Solution {
public:
int lengthOfLongestSubstring(string s) {
int l = s.size();
unordered_set<char> sub;
int end = 0,start = 0; //左右指针位置
int max=0;
for(end=0; end<l; end++){
if(!sub.count(s[end])){ //当前字符不重复
sub.insert(s[end]);
max = max>(sub.size())?max:(sub.size());
}
else{ //当前字符重复
max = max>(sub.size())?max:(sub.size());
sub.erase(s[start]);
start++;
end--;
}
}
return max;
}
};
感觉依旧不是最优解啊,有时间看看大佬都是怎么搞的吧。