#自己瞎摸索写的#
参考过很多的其他人的解法,然后自己写了一遍。
这道题用的是滑动窗口,用两重for循环暴力也可以解决
先判断边界条件(我自己做算法第一步就是找边界)
if(s==null||s.isEmpty()) return 0;
然后把字符串转成字符数组
char[] chars = s.toCharArray();
先搞两个指针
int fast = 0,slow = 0;
定义一个Map
Mapmap = new HashMap();
这里思想是:
字符数组: a b c b 快指针: f 慢指针: s
然后把快指针向右边移动,如果Map中没有该字符(fast指向的那个),那我们就把chars[fast]放进去,然后接着右移动fast,定义一个len记录fast和slow的差,然后把maxLen和len比较。
if(!map.containsKey(chars[fast])){
map.put(chars[fast],fast);
len++;
maxLen = Math.max(len,maxLen);
}
那如果刚好到了存在的地方了
字符数组: a b c b 快指针: f 慢指针: s
我们就右移慢指针,然后把右指针指的每个char[slow]给删除掉
这里一定要想清楚。比如说我们是在第四个位置碰到b重复,那么因为从前面遍历过来的,所以只有b这一个重复,不然比b先重复的肯定先查出来。所以第二个位置的b之前的所有字符都要删除,就像是
这个字符串,c重复了:
a b c d e f c d
删除a
b c d e f c d
还是重复呀
那我要再删
c d e f c d
还不是重复?
所以只有当c被删除的时候,在快慢指针的区间(也就是map集合存储的数据)才没有重复的数据
所以要一直删到slow这个位置以后
我们每删一个 len都要 - -
else if(map.containsKey(chars[slow])==map.containsKey(chars[fast])){
map.remove(chars[slow]);
len--;
slow++;
fast --;
}
这里fast++,是因为刚好当我们删除到slow后,进行了一次循环的fast++操作,会跳过一个(当时我也错了,忽略了这个问题,我调试过),所以要加回来
全部代码如下(可AC):
public static int lengthOfLongestSubstring(String s) {
if(s==null||s.isEmpty()) return 0;
char[] chars = s.toCharArray();
int fast = 0,slow = 0;
Map map = new HashMap();
int maxLen =0;
int len=0;
for (fast = 0; fast < s.length(); fast++) {
if(!map.containsKey(chars[fast])){
map.put(chars[fast],fast);
len++;
maxLen = Math.max(len,maxLen);
}else if(map.containsKey(chars[slow])==map.containsKey(chars[fast])){
map.remove(chars[slow]);
len--;
slow++;
fast --;
}
}
return maxLen;
}
本题是自己想的,可能有很多逻辑还有语法或者一些其他问题,仅仅只当做记录我刷leetcode的一次想法,可能下一次就不同了。




