题目
题解-滑动窗口
真的是…完全没思路,新方法get√
模式识别1:出现次数,用哈希表(构建子串,哈希表存下标)
模式识别2:涉及子串,考虑滑动窗口
本题思路是:用哈希表存子串,左右指针控制滑动窗口大小
- 如果窗口内没有重复字符,右指针移动一步
- 如果窗口内有重复字符,左指针移动一步
最后确定无重复字符的最长子串
class Solution {
public int lengthOfLongestSubstring(String s) {
int left=0;//左指针
int right=0;//右指针
int max=0;
Set<Character>hashSet=new HashSet<Character>();//记录子串
while(right<s.length()){
//无重复字符
if(!hashSet.contains(s.charAt(right))){
hashSet.add(s.charAt(right));
right++;
}
//有重复字符
else{
hashSet.remove(s.charAt(left));
left++;
}
if(right-left>max)
max=right-left;
}
return max;
}
}
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
m
)
O(m)
O(m),m是最长子串的长度
补充另外一个用map的方法,记录字符和下标,如果窗口内含有该字符,就移动左指针到该字符第一次出现的下一个位置
class Solution {
public int lengthOfLongestSubstring(String s) {
int n=s.length(),left=0,res=0;
Map<Character,Integer>map=new HashMap<>();
for(int right=0;right<n;right++){
char ch=s.charAt(right);
//如果map中含有ch,更新窗口左指针
if(map.containsKey(ch))
left=Math.max(left,map.get(ch)+1);
map.put(ch,right);//记录字符位置
res=Math.max(res,right-left+1);//更新最长子串长度
}
return res;
}
}
时间复杂度:
O
(
n
)
O(n)
O(n)
空间复杂度:
O
(
m
)
O(m)
O(m),m是最长子串的长度
P.S.注意一下java【charAt,add,contains】和c++字符串操作的不同
P.P.S.可以根据题解思路自己写出来了,而不是照着题解给的代码记,开心