3.无重复字符的最长子串(中等)
题目如下:
给定一个字符串,请你找出其中不含有重复字符的 最长子串 的长度。
示例 1:
输入: s = "abcabcbb"
输出: 3
解释: 因为无重复字符的最长子串是 "abc",所以其长度为 3。
示例 2:
输入: s = "bbbbb"
输出: 1
解释: 因为无重复字符的最长子串是 "b",所以其长度为 1。
示例 3:
输入: s = "pwwkew"
输出: 3
解释: 因为无重复字符的最长子串是 "wke",所以其长度为 3。
请注意,你的答案必须是 子串 的长度,"pwke" 是一个子序列,不是子串。
示例 4:
输入: s = ""
输出: 0
提示:
0 <= s.length <= 5 * 10
4s
由英文字母、数字、符号和空格组成
这道题一上来最有感觉的当然就是暴力枚举啦,但一想到就算通过了也就超过个百分之几,有啥意思吗
所以上来就是想最优解,其实很多最优解都是在一个循环下完事,往这方向冲就行了
这题按官方给的题解叫滑动窗口,其实就是用两个左右指针来实现的,我是写完后看题解才发现是一类的写法,跟官方同步上还是很开心
如果看到左右指针后还没啥想法的同学,建议去看官方的题解,他那个详细的一b,显然我只是简单写写
直接上代码,详细注释
可能说的不是很清楚,建议用示例1和示例3放上去模拟一下
我这里模拟下示例1,() 分别代表左右指针
(a)bcabcbb
(ab)cabcbb
(abc)abcbb
(abca)bcbb -> a(bca)bcbb (这一步操作都是if里完成的 就是左指针的变动)
a(bcab)cbb -> ab(cab)cbb
ab(cabc)bb -> abc(abc)bb
abc(abcb)b -> abcab(cb)b
abcab(cbb) -> abcabcb(b)
end
class Solution {
public int lengthOfLongestSubstring(String s) {
//看题目提示可知s由英文字母、数字、符号和空格组成 假设就是ascii码上常见的前128个
int[] array = new int[128];
//这个都懂
int max = 0;
//字面意思 左右指针
int left = 1;
int right = 1;
//一层循环就ok 右指针代表子串起点 左指针代表子串终点
for(int i = 0;i < s.length();i++){
//获取当前字符
char ch = s.charAt(i);
//array[ch] != 0 代表有重复字符了 array[ch] + 1 > left 是要判断重复字符是不是在left之后
//如果是在left之前 那就是之前出现的 不是本子串里
if(array[ch] != 0 && array[ch] + 1 > left){
//如果是本子串里出现重复 那么就跳到这个重复字符 第一次出现时的后面
left = array[ch] + 1;
}
//右指针是一直往后滑的
right++;
//每次都记录字符最新位置
array[ch] = i + 1;
//(右指针 - 左指针)就是长度
max = max > right - left ? max : right - left;
}
return max;
}
}