发布于个人公众号,打开微信,搜索
MelodyJerry即可
3. 无重复字符的最长子串
| 难度 | 中等 | 通过率 | 37.57% (1106175/2943963) |
|---|
给定一个字符串 s ,请你找出其中不含有重复字符的 最长子串 的长度。
示例 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<= s由英文字母、数字、符号和空格组成
题解
① 滑动窗口
-
滑动窗口,字串问题基本都可以用滑动窗口来处理。 -
什么是
滑动窗口?-
其实就是
双指针的特殊用法 -
通过
左右指针来维护一个动态的窗口 -
通过判断后
左指针滑动以实现缩小窗口,右指针滑动以实现增大窗口 -
再
进行窗口内数据的一系列更新操作 -
循环操作,在特定条件下,
更新答案
-
-
滑动窗口,这是一套框架技巧思维- 这个技巧的
时间复杂度是 - 远比字符串暴力要高效得多
- 这个技巧的
时间复杂度:
空间复杂度:
② 遍历字符串
来自社区,作者:VioletKiss
遍历字符串,每次以 i 值记录,不回溯 i 值,用flag记录遍历过程找到的重复的字符的位置。如果遇到重复字符,i-flag 即为子串长度,此时flag重新定位到子串中重复字符的位置,i 继续往后遍历。这里length跟result记录长度。
class Solution {
public int lengthOfLongestSubstring(String s) {
if (s.length() < 2) return s.length();
int flag=0;//子串起始位置
int max = 0;
int len = 0;
for (int i = 0; i < s.length(); i++) {
int index = s.indexOf(s.charAt(i),flag);
if(index < i){//从flag开始 出现了重复字符
if(max<len){//记录len
max = len;
}
flag = index+1;//记录子串起始位置
len = i-flag+1;//重新计算字串长度
}
else{
len++;
}
}
return len>max?len:max;//若最后一个子串没有出现重复字符就需要判断
}
}
class Solution {
public int lengthOfLongestSubstring(String s) {
//a b c a b c d a d e
//0 1 2 3 4 5 6 7 8 9
int maxSize = 0;
//记录ASCII 码字符出现的位置,以字符作为下标
int[] dict = new int[128];
//为了方便理解,这里把数组内容全部设为 -1,之后在记录的时候就可以从 0 开始,方便理解
Arrays.fill(dict, -1);
//用于记录重复 ASCII 码字符出现的位置的值
int repeatValue = -1;
// 当前下标
int i = 0;
int ASCII;
while (i < s.length()) {
ASCII = s.charAt(i);
//如果当前位置的值 > repeatValue,证明当前位置已经赋过一次值了,证明字符重复
if (dict[ASCII] > repeatValue)
//更新 repeatValue 为之前赋值的下标
repeatValue = dict[ASCII];
//将当前下标赋值到数组相应位置
dict[ASCII] = i;
//i - repeatValue(去除重复部分)
// 比如 abcabcdade 中的三个 a 的计算 abca - a(3 - 0)=bca abcabcda - abca(7 - 3)=bcda
maxSize = Math.max(maxSize, i - repeatValue);
//s.length() - repeatValue - 1 判断剩下的数有没有必要继续循环
//比如 abcabcdade 最后的 a(当 i = 7 repeatValue = 3) ,abcabcdade - abca(10-3-1) = bcdade 剩下最多有六位
//比如 abcabcdade 最后的 d(当 i = 8 repeatValue = 6) ,abcabcdade - abcabcd(10-6-1) = ade 剩下最多也是三位
if (maxSize >= s.length() - repeatValue - 1) {
return maxSize;
}
i++;
}
return maxSize;
}
}