滑动窗口算法与JS

1,642 阅读2分钟

最近刷题看到字符串和数组相关的题目很多都有这个滑动窗口,但我对滑动窗口的印象还停留在TCP的滑动窗口,赶紧补一下这块知识。

什么是滑动窗口

image.png

滑动窗口算法也叫双指针算法,多用于特定大小的数组或字符串,使用一个大小可变动的“窗口”,按固定方向滑动,遍历字符串或数组,寻找其中符合要求的部分。从而降低循环嵌套的深度,压低了复杂度,某种程度上说是空间换时间的办法,

滑动窗口不能算某种固定的Function,更接近于一种办法。

怎样构建滑动窗口

  • 滑动: 说明这个窗口是移动的,也就是移动是按照一定方向来的。
  • 窗口: 窗口大小并不是固定的,可以不断扩容直到满足一定的条件;也可以不断缩小,直到找到一个满足条件的最小窗口;当然也可以是固定大小。

具体步骤

  1. 我们在字符串 S 中使用双指针中的左右指针技巧,初始化 left = right = 0,把索引闭区间 [left, right] 称为一个「窗口」。
  2. 我们先不断地增加 right 指针扩大窗口 [left, right],直到窗口中的字符串符合要求(包含了 T 中的所有字符)。
  3. 此时,我们停止增加 right,转而不断增加 left 指针缩小窗口 [left, right],直到窗口中的字符串不再符合要求(不包含 T 中的所有字符了)。同时,每次增加 left,我们都要更新一轮结果。
  4. 重复第 2 和第 3 步,直到 right 到达字符串 S 的尽头。

练习

LeetCode 15 三数之和

描述

给你一个包含 n 个整数的数组 nums,判断 nums 中是否存在三个元素 a,b,c ,使得 a + b + c = 0 ?请你找出所有和为 0 且不重复的三元组。

注意:答案中不可以包含重复的三元组。 

示例 1:

输入:nums = [-1,0,1,2,-1,-4]
输出:[[-1,-1,2],[-1,0,1]]

示例 2:

输入:nums = []
输出:[]

示例 3:

输入:nums = [0]
输出:[]

提示:

0 <= nums.length <= 3000
-105 <= nums[i] <= 105

解题

比起两数之和,这道题用滑动窗口解题的前提是数组已排序

var threeSum = function(n) {
    const target = 0;
    let result = [];

    // 对原数组从大到小排序
    let nums = n.sort((a,b) =>{return a-b});
    
    // 指定 a
    for(let i=0; i<nums.length-1; i++){
        
        // 设置左右双指针,从nums两端开始,寻找符合要求的b,c
        let left = i+1;
        let right = nums.length - 1;
        
        // 当左右双指针相遇,本次搜索结束
        while(left < right){
            let sum = nums[i] + nums[left] + nums[right];

            // 发现符合要求的三数之和
            if(sum === target){
                result.push([nums[i],nums[left],nums[right]]);
                console.log(nums[i],nums[left],nums[right])
                left ++;
            }
            else{
                // 和偏小,指针右移扩大数值
                if(sum < target){
                    left ++;
                    continue;
                }
                // 和偏大,指针左移减小数值
                else if(sum > target){
                    right --;
                    continue;
                }
            }
        }
    }
    
    console.log(result)
};

参考

滑动窗口算法基本原理与实践
精读《算法 - 滑动窗口》