辛辣天塞!滑动窗口之【和的最大值】&【最大值集合】

简介: 本篇带来两道经典的关于滑动窗口的算法题,有兴趣可在控制台跑一跑~

image.png

本篇带来两道经典的关于滑动窗口的算法题,有兴趣可在控制台跑一跑~


求和的最大值



题目来源:上一篇掘文《温故知新 —— Sliding Window》


比如给定如下数组:[ 5, 7, 1, 4, 3, 6, 2, 9, 2 ],求出 5 个连续元素的最大和是多少?

[5, 7, 1, 4, 3] 是第一组 5 个连续元素,求和是 20[7, 1, 4, 3, 6] 是第二组 5 个连续元素,求和是 21......这样一直进行下去,最终对比发现 5 个连续元素的最大和是 24,由 [4, 3, 6, 2, 9] 组成;


这里给出本瓜的另一种写法,仅供参考:


var maxSlidingWindow = function(nums, k) {
   const sum = function (arr) {
        return arr.reduce(function(prev, curr, idx, arr){
            return prev + curr;
        });
    };
    let slidingWindow=nums.slice(0,k)
    let newSlidingWindow=[]
    let maxVal;
    for(let i=k;i<nums.length;i++){
        newSlidingWindow=slidingWindow.slice(1).concat(nums[i])
        maxVal=Math.max(sum(slidingWindow),sum(newSlidingWindow))
        slidingWindow = newSlidingWindow
    }
    return maxVal
};
const nums= [ 5, 7, 1, 4, 3, 6, 2, 9, 2 ]
const k=5
maxSlidingWindow(nums,k) // 24


求最大值集合



题目来源:leetcode-239 (复杂)

给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。

返回滑动窗口中的最大值。

输入:nums = [1,3,-1,-3,5,3,6,7], k = 3
输出:[3,3,5,5,6,7]
解释:
滑动窗口的位置                最大值
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7


本题在力扣中,难度被标为:复杂,这复杂吗?

  1. 写一个函数来判断数组中最大的数;
  2. 初始化窗口,求最大值保存;
  3. 滑动窗口,再求最大值保存;
  4. 滑动直至完毕;


本瓜题解:

/**
 * @param {number[]} nums
 * @param {number} k
 * @return {number[]}
 */
var maxSlidingWindow = function(nums, k) {
  if(k===1) return nums; // 特殊情况
  let slidingWindow = nums.slice(0,k)
  let newSlidingWindow = []
  let resArr = []
  resArr.push(Math.max(...slidingWindow))
  for(let i=k;i<nums.length;i++){
      newSlidingWindow = slidingWindow.slice(1).concat(nums[i])
      resArr.push(Math.max(...newSlidingWindow))
      slidingWindow = newSlidingWindow
  }
  return resArr
};


结果,当数组长度为 10 w 时,报错 超出时间限制

噢!用 Math.max() 来每次从窗口找最大值,时间复杂度是 O(n * k),仍然很大;

窗口固定,求最大值集合 在根本上是 单调队列 的问题!

本瓜录屏了一个非常棒的动画效果解释:

image.png


最后 JS 题解:

var maxSlidingWindow = function (nums, k) {
  // 队列数组(存放的是元素下标,为了取值方便)
  const q = [];
  // 结果数组
  const ans = [];
  for (let i = 0; i < nums.length; i++) {
    // 若队列不为空,且当前元素大于等于队尾所存下标的元素,则弹出队尾
    while (q.length && nums[i] >= nums[q[q.length - 1]]) {
      q.pop();
    }
    // 入队当前元素下标
    q.push(i);
    // 判断当前最大值(即队首元素)是否在窗口中,若不在便将其出队
    while (q[0] <= i - k) {
      q.shift();
    }
    // 当达到窗口大小时便开始向结果中添加数据
    if (i >= k - 1) ans.push(nums[q[0]]);
  }
  return ans;
};

实际上,滑动窗口还是有很多扩展的空间,即使是窗口滑动,怎么滑,滑动后怎么做,里面就存在很大的解题思路的差异!

以上。


相关文章
|
Python
matplotlib 按指定的时间间隔生成坐标轴
matplotlib 提供了自定义生成时间轴的库,而当我们需要按照自己定义的时间间隔去生成时间轴时,时间轴并没有正常显示,只是按照一个时间跨度更大的方式显示,本文强制 matplotlib 严格按照要求自定义的时间间隔来坐标轴,并对每一行代码做了详细的说明。
7395 0
matplotlib 按指定的时间间隔生成坐标轴
|
7月前
|
安全 Ubuntu Linux
Nexpose 8.3.0 发布 - 领先的漏洞管理解决方案
Nexpose 8.3.0 for Linux & Windows - 领先的漏洞管理解决方案
123 6
Nexpose 8.3.0 发布 - 领先的漏洞管理解决方案
|
数据挖掘 Linux 数据处理
探索Linux下的Lua命令:轻量级脚本语言在数据处理和分析中的应用
**探索Linux上的Lua:轻量级脚本语言用于数据处理。Lua通过命令行解释器执行,适用于游戏开发、数据分析及自动化。特点包括小巧、高效、可扩展和动态类型。使用`lua`或`luajit`,配合-e、-l、-i参数执行脚本或互动模式。示例:执行`hello.lua`脚本打印&quot;Hello, Lua!&quot;。最佳实践涉及版本兼容、性能优化、使用C API、测试和文档编写。**
|
定位技术
ENVI: 如何创建GLT文件并基于GLT对图像进行几何校正?
ENVI: 如何创建GLT文件并基于GLT对图像进行几何校正?
1551 0
|
Python
Python mplfinance库④ 如何自定义style样式
Python mplfinance库④ 如何自定义style样式
1886 0
Python mplfinance库④ 如何自定义style样式
|
C语言
安装mujoco报错:distutils.errors.DistutilsExecError: command ‘gcc‘ failed with exit status 1
安装mujoco报错:distutils.errors.DistutilsExecError: command ‘gcc‘ failed with exit status 1
960 0
|
数据安全/隐私保护
URL编码解析方式-特殊字符加密和解密
URL编码解析方式-特殊字符加密和解密
305 0
|
存储 算法 网络架构
【Hello Algorithm】滑动窗口内最大值最小值
【Hello Algorithm】滑动窗口内最大值最小值
270 0
|
Python
python股票量化交易(9)---使用TA-Lib库实现股价走势对比图
python股票量化交易(9)---使用TA-Lib库实现股价走势对比图
1456 1
python股票量化交易(9)---使用TA-Lib库实现股价走势对比图