滑动窗口算法模板

这里摘抄《labuladong的算法小抄》中的一首小诗(东哥大才):

滑动窗口防滑记

链表子串数组题,用双指针别犹豫。双指针家三兄弟,各个都是万人迷。

快慢指针最神奇,链表操作无压力。归并排序找中点,链表成环搞判定。

左右指针最常见,左右两端相向行。反转数组要靠它,二分搜索是弟弟。

滑动窗口最困难,子串问题全靠它。左右指针滑窗口,一前一后齐头进。

labuladong稳若”狗“,一套框架不翻车。一路漂移带闪电,算法变成默写题。

滑动窗口算法技巧的思路非常简单,就是维护一个窗口,不断滑动,然后更新答案。该算法的大致逻辑如下:

        int left = 0, right = 0;

        while (right < s.size()) {

                // 增大窗口

                window.add(s[right]);

                right++;

                while (window needs shrink) {

                        // 缩小窗口

                        window.remove(s[left]);

                        left++;

                }

        }

这个算法的时间复杂度是O(N),比字符串暴力算法要高效得多。下面是东哥的一套滑动窗口算法的代码框架,连在哪里做输出 debug 都写好了,以后遇到相关的问题,就默写出来如下框架然后修改两个地方就行,还不会出 bug:

package SlidingWindow;

import java.util.HashMap;
import java.util.Map;

// 算法模板—滑动窗口
public class AlgorithmTemplate {

    public void slidingWindow(String s, String t) {
        Map<Character, Integer> need = new HashMap<>();
        Map<Character, Integer> window = new HashMap<>();
        for (int i = 0; i < t.length(); i++) {
            char key = t.charAt(i);
            need.put(key, need.getOrDefault(key, 0) + 1);
        }
        int left = 0, right = 0, valid = 0;
        while (right < s.length()) {
            // c 是将要移入窗口的字符
            char c = s.charAt(right);
            // 右移窗口
            right++;
            // 进行窗口内数据的一系列更新
            System.out.println("进行窗口内数据的一系列更新");

            /*** debug 输出的位置***/
            System.out.println("window:(" + left + ", " + right + ")");
            /*********************/

            // 判断左侧窗口是否要收缩
            while (true) { // window need shrink —窗口需要收缩
                // d 是将要移出窗口的字符
                char d = s.charAt(left);
                // 左移窗口
                left++;
                // 进行窗口内数据的一系列更新
                System.out.println("进行窗口内数据的一系列更新");
            }
        }
    }
}

其中两处 sout 表示更新窗口数据的地方,直接往里面填具体逻辑就行了。而且,这两处操作分别是右移和左移窗口更新操作,它们的操作是完全对称的。稍后,我会用4道力扣原题来套这个框架。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值