从生活案例理解滑动窗口最大值:一个超直观的思路讲解|LeetCode 239 滑动窗口最大值
LeetCode 239 滑动窗口最大值
点此看全部题解 LeetCode必刷100题:一份来自面试官的算法地图(题解持续更新中)
更多干货,请关注公众号【忍者算法】,回复【刷题清单】获取完整题解目录~
用生活中的例子来理解
想象你是一位摄影师,在拍摄一场马拉松比赛。你的相机一次只能拍摄3个跑步者(就像一个宽度为3的窗口)。随着比赛进行,你的镜头不断向前移动,每次只移动一点点,要在每张照片中找出最高的那位跑步者的身高。这就是我们今天要解决的"滑动窗口最大值"问题。
问题是什么
LeetCode第239题给我们一个任务:假设有一个数组,比如 [2,3,4,2,6,2,5,1],然后给我们一个宽度为3的窗口。这个窗口会从左往右滑动,每次移动一格。我们需要记录下每个窗口中的最大值。
举个简单的例子:
数组:[2,3,4] 窗口大小:2
第一个窗口:[2,3] 4 最大值是3
第二个窗口:2 [3,4] 最大值是4
所以最终结果是:[3,4]
最简单的解决方案:看一看比一比
就像我们肉眼看照片找最高的人一样,最简单的方法就是每次都看窗口里的所有数字,找出最大的那个。
// 这是最容易理解的方法
public int[] maxSlidingWindow(int[] nums, int k) {
int[] result = new int[nums.length - k + 1]; // 存放结果
// 对每个窗口进行处理
for (int i = 0; i <= nums.length - k; i++) {
int max = nums[i]; // 假设窗口第一个数是最大的
// 看看窗口里其他数是不是更大
for (int j = 1; j < k; j++) {
if (nums[i + j] > max) {
max = nums[i + j];
}
}
result[i] = max; // 记录这个窗口的最大值
}
return result;
}
这个方法很直观,就像用眼睛一个一个数字比较。但是,如果数组很长,窗口很大,这样做就会很慢。
聪明的解决方案:排队游戏
现在我们来学一个更聪明的方法。想象一个游戏:
- 我们有一群小朋友排队,每个小朋友手里举着一个数字牌。
- 我们要保证队伍里的小朋友,从前到后手里的数字是从大到小的。
- 当新的小朋友要进队时,就要把队伍后面所有比他数字小的小朋友请出队。
- 队伍最前面的小朋友,就是当前窗口的最大值。
用代码来实现这个想法:
public int[] maxSlidingWindow(int[] nums, int k) {
// 如果数组是空的,直接返回空数组
if (nums == null || nums.length == 0) return new int[0];
int[] result = new int[nums.length - k + 1]; // 存放结果
Deque<Integer> queue = new LinkedList<>(); // 这就是我们的"队伍"
for (int i = 0; i < nums.length; i++) {
// 第一步:如果队伍最前面的小朋友已经不在窗口范围内了,请他离开
if (!queue.isEmpty() && queue.peek() < i - k + 1) {
queue.poll();
}
// 第二步:新小朋友要入队,
// 把队尾所有比新小朋友数字小的都请出队
while (!queue.isEmpty() && nums[queue.peekLast()] < nums[i]) {
queue.pollLast();
}
// 第三步:新小朋友入队
queue.offer(i);
// 第四步:如果窗口已经形成,记录当前最大值
if (i >= k - 1) {
result[i - k + 1] = nums[queue.peek()];
}
}
return result;
}
让我们用一个具体的例子来看这个过程:
数组:[3,1,4,2] 窗口大小:2
初始状态:队伍为空
1. 数字3来了:
队伍:[3]
2. 数字1来了:
因为1比3小,直接排在3后面
队伍:[3,1]
第一个窗口的最大值是3
3. 数字4来了:
4比1大,1离开队伍
4比3大,3离开队伍
队伍:[4]
第二个窗口的最大值是4
4. 数字2来了:
2比4小,直接排在4后面
队伍:[4,2]
第三个窗口的最大值是4
为什么这样做更好?
- 每个数字最多只会进队一次,出队一次
- 我们不用每次都看窗口里的所有数字
- 队伍的最前面永远是当前窗口的最大值
这就像在拍马拉松照片时,不用每次都量所有人的身高,而是保持一个有序的记录,随时知道当前画面中最高的人是谁。
小结
解决滑动窗口最大值问题,关键是要想到:
- 我们不需要记住窗口里的所有数
- 只需要保持一个"从大到小"的顺序
- 及时把不在窗口范围内的数字删除
这样,我们就把一个看起来很复杂的问题,变成了一个简单的"排队游戏"!
作者:忍者算法
公众号:忍者算法
c2f29413-f36f-4fc1-a443-9eabbdb400bc
从生活案例理解滑动窗口最大值:一个超直观的思路讲解|LeetCode 239 滑动窗口最大值的更多相关文章
- 代码随想录算法训练营day12 | leetcode 239. 滑动窗口最大值 347.前 K 个高频元素
基础知识 ArrayDeque deque = new ArrayDeque(); /* offerFirst(E e) 在数组前面添加元素,并返回是否添加成功 offerLast(E e) 在数组后 ...
- Leetcode 239.滑动窗口最大值
滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口 k 内的数字.滑动窗口每次只向右移动一位. 返回滑动窗口最大值. 示例: ...
- LeetCode(239.滑动窗口的最大值
题目: 给定一个数组nums,有一个大小为k的滑动窗口从数组的最左侧移动到最右侧,你只可以看到滑动窗口内的k个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示例: 输入: nums = ...
- Java实现 LeetCode 239 滑动窗口最大值
239. 滑动窗口最大值 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最 ...
- leetcode 239. 滑动窗口最大值(python)
1. 题目描述 给定一个数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 示 ...
- 【leetcode 239. 滑动窗口最大值】解题报告
思路:滑动窗口的思想,只要是求连续子序列或者子串问题,都可用滑动窗口的思想 方法一: vector<int> maxSlidingWindow(vector<int>& ...
- 代码随想录第十三天 | 150. 逆波兰表达式求值、239. 滑动窗口最大值、347.前 K 个高频元素
第一题150. 逆波兰表达式求值 根据 逆波兰表示法,求表达式的值. 有效的算符包括 +.-.*./ .每个运算对象可以是整数,也可以是另一个逆波兰表达式. 注意 两个整数之间的除法只保留整数部分. ...
- 【leetcode】239. 滑动窗口最大值
目录 题目 题解 三种解法 "单调队列"解法 新增.获取最大值 删除 代码 题目 给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以 ...
- 【每日一题】【双端降序队列Deque】2021年12月28日-239. 滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧.你只可以看到在滑动窗口内的 k 个数字.滑动窗口每次只向右移动一位. 返回滑动窗口中的最大值. 来源:力扣(L ...
- 理解SetCapture、ReleaseCapture、GetCapture(控制了消息发往哪个窗口,是理解消息的关键)
理解SetCapture.ReleaseCapture.GetCapture 正常情况下,鼠标指针位于哪个窗口区域内,鼠标消息就自动发给哪个窗口.如果调用了SetCapture,之后无论鼠标的位置在哪 ...
随机推荐
- php生成树状层级子孙树-迭代篇
关于简单的方式获取树状层级子孙树的方案我已经写过了,在这里,当时是用简单的递归实现的,但是现在回头想想,如果层级很多,数据也很多,用递归感觉还是会不稳妥,这就有必要想办法转换为迭代来实现了. 以下是迭 ...
- Maven多模块项目 eclipse热部署 Maven项目实现 tomcat热部署
Maven 多模块项目在eclipse下面热部署,即你可以体验下无论你修改整个项目里面的任何模块的代码,都不需要用maven打包就可以看到效果, 1.首先准备好创建一个maven多项目的代码,准备好一 ...
- 四、FreeRTOS学习笔记-任务创建和删除
FreeRTOS的任务创建和删除 1,任务创建和删除的API函数(熟悉) 任务的创建和删除本质就是调用FreeRTOS的API函数 一.任务创建 动态创建任务:任务的任务控制块以及任务的栈空间所需的内 ...
- Mac下常用软件汇总(精)
1.连接Windows远程连接工具(Microsoft-Remote-Desktop-For-Mac ) 2.SSH管理工具:Royal TSX 下载地址:Royal Apps Royal TSX 是 ...
- 2016GPLT
排座位 从1到N编号:M为已知两两宾客之间的关系数:K为查询的条数.随后M行,每行给出一对宾客之间的关系,格式为:宾客1 宾客2 关系,其中关系为1表示是朋友,-1表示是死对头.注意两个人不可能既是朋 ...
- Nuxt.js 应用中的 dev:ssr-logs 事件钩子
title: Nuxt.js 应用中的 dev:ssr-logs 事件钩子 date: 2024/11/28 updated: 2024/11/28 author: cmdragon excerpt: ...
- 使用 fiddler 进行抓包处理
1.概述 fiddler是一个抓包工具,有时候方便我们在访问网页上,看看网页的参数和返回结果.其中很重要的一条是,可以查看网页的响应速度,在对于调优方面提供一些依据. 2.软件安装 我们可以通过360 ...
- HBuilderX代码缩进问题
前情 uni-app是我很喜欢的跨平台框架,它能开发小程序,H5,APP(安卓/iOS),对前端开发很友好,自带的IDE让开发体验也很棒,公司项目就是主推uni-app,自然也是用官方自带的IDE了 ...
- git clone 指定 ssh-key 文件
环境 & 软件 mac OS 问题 git clone 不是默认 ssh-key,无法克隆 解决方法 用ssh-add命令将对应的私钥加入到缓存 // ssh-add 自定义名称 // 例子 ...
- Qt编写视频监控系统76-Onvif跨网段组播搜索和单播搜索的实现
一.前言 在视频监控行业一般会用国际onvif工具来测试设备是否支持onvif协议,工具的名字叫ONVIF Device Manager(还有个工具叫ONVIF Device Test Tool,专用 ...