无重复最长子串
滑动窗口
1.窗口的滑动
2.窗口的内容
本体要求窗口内无重复,用set来保障么没有重复,不要忘记right位置一定要添加到set中
因为便利的是right,遍历right复杂度是n
class Solution {
public int lengthOfLongestSubstring(String s) {
//左右指针记录窗口起始结束位置,遍历结束位置
//记录最大窗口大小
//用Set记录是否遍历过
int result = 0;
int left = 0;
int right = 0;
Set<Character> set = new HashSet<>();
for(;right < s.length();right++){
char c = s.charAt(right);
if(set.contains(c)){
while(set.contains(c)){
set.remove(s.charAt(left++));
}
}
set.add(c);
result = Math.max(result,right - left + 1);
}
return result;
}
}
class Solution {
public int characterReplacement(String s, int k) {
//暴力求解,遍历每个字符串 n^2
//对每个字符串进行判断,如果改k个可以记录记录长度,最后取最长。
//滑动窗口,鉴于取最大值,只需要最大窗口长度不受污染就可以,只需要在窗口需要变大时更新
//遍历端口的右端点,最长出现字符的次数,窗口大小-最大出现次数 > k 则left向前移动一位(因为right是遍历一直加一)保证窗口大小不会变化
//只有当窗口大小-最大出现次数 <= k的时候可以尝试加大窗口。
//记录字母出现次数
int[] alphabet = new int[26];
int right = 0;
int left = 0;
int max = 0;
int result = 0;
for(;right < s.length();right++){
int index = s.charAt(right) - 'A';//右端字母索引
alphabet[index]++;//对应字母出现次数增加
int size = right - left + 1;//窗口大小
max = Math.max(max,alphabet[index]);
if(size - max > k){
alphabet[s.charAt(left) - 'A']--;//删除最左侧的字母,此时删除可能会导致当前窗口内的字母不符合要求,但是窗口大小不会变大变小,不影响最终结果
left++;
}
result = Math.max(result,right - left +1 );
}
return result;
}
}