【经典专题】爬行的毛毛虫——简单的滑动窗口模板

news/2024/5/20 7:06:37 标签: 面试, 算法, 滑动窗口, 模板

经典例题

给你一个由大写英文字母组成的字符串,你可以将任意的字符替换成另一个字符,但最多可替换 k 次。在执行上述操作后,找到包含重复字母的最长子串的长度。
 
输入:s = “AABABA”, k = 1
输出:4
解释:将中间的一个’B’替换为’A’,字符串变为 “AAAABA”。

 
 

滑窗模板

public int SlidingWindow(String s) {
	len = s.length();			// 串的长度
	int[] count = new int[N];	// 用于统计区间内的信息
	int L = 0, R = 0;			// 窗口边界,这是一个闭区间[L, R]
	int res = 0;				// 窗口最大宽度(最终结果)
	while (R < len) {
		count[s.charAt(R)]++;			// 修改统计值,因为R的移动改变了窗口
		while (区间不符合题意) {
			count[s.charAt(L)]--;		// 修改统计值,因为L的移动改变了窗口
			L++;						// 左指针被动移动(虫子的尾部)
		}
		res = Math.max(res, R - L + 1);		// 尝试更新res
		R++;								// 右指针主动移动(虫子的头部)
	}
}

 
 

模板说明

  1. 这篇文章的作者(here)提出了一个比滑动窗口更加生动形象的名字,虫取法。像一只蠕动前行的毛毛虫,后脚不动前脚向前方伸去,前脚不动后脚被拖拽跟上。
  2. 因此模板的核心思想就是:以右指针为驱动,拖着左指针向前走——右指针主动移动,探索新的区域;左指针被迫跟进,负责保证区间符合题意。
  3. 右指针的移动是一个 固定 的动作,每次固定移动一步,因此在内层的那个while之外;左指针的移动是一个 被迫 的动作,每次移动的步数并不确定,因此在内层的那个while之中。

 
 

一些理解

  1. 这里题目中,给出的可能是字符串/数组,将字符串转化为数组(toCharArray)会得到不小的性能优化哦
  2. 滑窗的本质是一个合法区间,既然是区间,就涉及到了所谓双指针。其实,“双指针”这个说法过于宽泛,一般而言的双指针,通常是两个(甚至三个、四个)指针从整体的两侧边界向内收缩,可以认为两个指针的方向是「相向而行」;而滑动窗口,区间不倾向于收缩而是倾向于移动,可以认为两个指针的方向是「同向而行

 
 

本题答案

>>> 1.count数组统计的是区间内每个字母出现的次数,并维护了出现次数最多的字母的出现次数maxCnt
>>> 2.关于区间的合法性,用了一个巧妙的判断:maxCnt + k < R - L + 1(🌟🌟🌟)
>>> 2.(出现次数最多的字母的出现次数+容错次数即可替换次数k)都无法填满这个窗口(R-L+1)的话,则非法了

>>> 3.还有一个小细节可能需要理解,就是内层while可以写成if
>>> 3.这是因为在本题中,可以保证由于R走了一步而导致到非法,L走一步就一定能纠正回来———天机在于maxCnt此时并未维护,while循环仅仅会执行一次
class Solution {
    public int characterReplacement(String s, int k) {
        int len = s.length();
		char[] charArr = s.toCharArray();
        int[] count = new int[26];
        int maxCnt = 0;

        int L = 0, R = 0;
        int res = 0;
        while (R < len) {
            count[charArr[R] - 'A']++;
            maxCnt = Math.max(maxCnt, count[charArr[R] - 'A']);
            while (maxCnt + k < R - L + 1) {
                count[charArr[L] - 'A']--;
                L++;
            }
            res = Math.max(res, R - L + 1);
            R++;
        }
        return res;
    }
}

 
 

更多内容

关于滑动窗口的更多内容请戳这里:《【图解算法模板的优化与进阶——滑动窗口专题

 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

E N D END END


http://www.niftyadmin.cn/n/1330090.html

相关文章

面试刷题笔记

Java学习大纲(持续更新) 更多IT学习资源 算法学习 算法 5:最长回文子串 多线程 1114. 按序打印 1115. 交替打印FooBar 1116. 打印零与奇偶数 面试套题 字节跳动2018校招测试开发方向&#xff08;第一批&#xff09; 字节跳动2019春招研发部分编程题汇总 字节跳动2018校招…

【图解算法】模板的优化与进阶——滑动窗口专题

Part1. 模板题 题目0&#xff1a;滑窗模板 public int SlidingWindow(String s) {len s.length(); // 串的长度int[] count new int[N]; // 用于统计区间内的信息int L 0, R 0; // 窗口边界&#xff0c;这是一个闭区间[L, R]int res 0; // 窗口最大宽度(最终结果)…

Java多线程刷题(LeetCode-1115. 交替打印FooBar)

ACM刷题 Java学习笔记 我们提供一个类&#xff1a;class FooBar {public void foo() {for (int i 0; i < n; i) {print("foo");}}public void bar() {for (int i 0; i < n; i) {print("bar");}} } 两个不同的线程将会共用一个 FooBar 实例。其中一…

【经典专题】颠簸的波浪——摆动数组问题的标准答案

引入定义 如果连续数字之间的差严格地在正数和负数之间交替&#xff0c;称为摆动数组。 举几个例子。[1,7,4,9,2,5]是一个典型的摆动数组&#xff0c;它就像颠簸的波浪&#xff1b;[1,7,4,5,5]不是摆动数组&#xff0c;因为它不是严格的上下摆动&#xff1b;[1]和[1,5]都符合…

LeetCode刷题笔记 - 1116. 打印零与奇偶数(多线程)

强烈推荐&#xff1a;LeetCode刷题笔记 文章目录题目Code 1 : 信号量法题目 假设有这么一个类&#xff1a;class ZeroEvenOdd {public ZeroEvenOdd(int n) { ... } // 构造函数public void zero(printNumber) { ... } // 仅打印出 0public void even(printNumber) { ...…

【LeetCode】Sama的个人记录_48

>>> 维护一个长度固定为len-k的滑动窗口&#xff0c;窗口里的和最小&#xff0c;窗口外(即边上的k张牌)的和就最大public int maxScore(int[] cardPoints, int k) {int len cardPoints.length;int point 0; // point存放窗口内的和int sum 0; // sum存放整个数组…

十五次架构演进

点击获得更多学习路线 文章目录概念介绍0.单机架构1.Tomcat与数据库分开部署2.引入本地缓存和分布式缓存3.引入反向代理实现负载均衡4.数据库读写分离5.数据库按业务分库6.把大表拆分为小表7.用LVS或F5来使多个Nginx负载均衡8.通过DNS轮询实现机房间的负载均衡9.引入NoSQL数据库…

【LeetCode】Sama的个人记录_49

>>> 不要一个个斜行去判断&#xff0c;而是一个个横行去判断class Solution {public boolean isToeplitzMatrix(int[][] matrix) {for(int i 1; i < matrix.length; i) {for(int j 1; j < matrix[0].length; j) {if(matrix[i][j] ! matrix[i - 1][j - 1]) {re…