滑动窗口最大值
难度:
标签:
题目描述
给你一个整数数组 nums
,有一个大小为 k
的滑动窗口从数组的最左侧移动到数组的最右侧。你只可以看到在滑动窗口内的 k
个数字。滑动窗口每次只向右移动一位。
返回 滑动窗口中的最大值 。
示例 1:
输入: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
示例 2:
输入:nums = [1], k = 1 输出:[1]
提示:
1 <= nums.length <= 105
-104 <= nums[i] <= 104
1 <= k <= nums.length
代码结果
运行时间: 156 ms, 内存: 0.0 MB
/*
* Problem: Find the maximum value in each sliding window of size k in the given array nums.
* Solution: This approach leverages Java Streams to find the max value for each window.
* Note: Streams are not the most efficient solution for this problem, but this is an illustration.
*/
import java.util.stream.IntStream;
import java.util.Arrays;
public class Solution {
public int[] maxSlidingWindow(int[] nums, int k) {
if (nums == null || nums.length == 0) return new int[0];
int n = nums.length;
return IntStream.rangeClosed(0, n - k)
.map(i -> Arrays.stream(nums, i, i + k).max().getAsInt())
.toArray();
}
}
解释
方法:
该题解使用双端队列实现了单调队列,维护了一个队列存储窗口内的元素下标。通过控制队列的进出,保证队首下标对应的元素始终是当前窗口内的最大值。在窗口滑动的过程中,不断将队尾元素与当前元素比较,将小于当前元素的下标弹出,并将当前元素下标加入队尾。当窗口形成后,每次将队首元素对应的值加入输出数组中。同时,当窗口滑出某个下标时,若该下标是队首元素,则将其从队列中弹出。
时间复杂度:
O(n)
空间复杂度:
O(k)
代码细节讲解
🦆
在算法中,为什么选择使用双端队列而不是其他数据结构如数组或链表来实现这个单调队列?
▷🦆
双端队列中存储的是元素的下标而不是元素的值,这样做有什么特别的优势吗?
▷🦆
你如何确保队列的单调递减性在整个窗口滑动过程中得到保持?具体是通过哪些操作实现的?
▷🦆
当队列中元素的下标已经不在窗口范围内时,你是如何处理的?请解释为什么需要这样做。
▷相关问题
最小覆盖子串
给你一个字符串 s
、一个字符串 t
。返回 s
中涵盖 t
所有字符的最小子串。如果 s
中不存在涵盖 t
所有字符的子串,则返回空字符串 ""
。
注意:
- 对于
t
中重复字符,我们寻找的子字符串中该字符数量必须不少于t
中该字符数量。 - 如果
s
中存在这样的子串,我们保证它是唯一的答案。
示例 1:
输入:s = "ADOBECODEBANC", t = "ABC" 输出:"BANC" 解释:最小覆盖子串 "BANC" 包含来自字符串 t 的 'A'、'B' 和 'C'。
示例 2:
输入:s = "a", t = "a" 输出:"a" 解释:整个字符串 s 是最小覆盖子串。
示例 3:
输入: s = "a", t = "aa" 输出: "" 解释: t 中两个字符 'a' 均应包含在 s 的子串中, 因此没有符合条件的子字符串,返回空字符串。
提示:
m == s.length
n == t.length
1 <= m, n <= 105
s
和t
由英文字母组成
进阶:你能设计一个在
o(m+n)
时间内解决此问题的算法吗?最小栈
设计一个支持 push
,pop
,top
操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack
类:
MinStack()
初始化堆栈对象。void push(int val)
将元素val推入堆栈。void pop()
删除堆栈顶部的元素。int top()
获取堆栈顶部的元素。int getMin()
获取堆栈中的最小元素。
示例 1:
输入: ["MinStack","push","push","push","getMin","pop","top","getMin"] [[],[-2],[0],[-3],[],[],[],[]] 输出: [null,null,null,null,-3,null,0,-2] 解释: MinStack minStack = new MinStack(); minStack.push(-2); minStack.push(0); minStack.push(-3); minStack.getMin(); --> 返回 -3. minStack.pop(); minStack.top(); --> 返回 0. minStack.getMin(); --> 返回 -2.
提示:
-231 <= val <= 231 - 1
pop
、top
和getMin
操作总是在 非空栈 上调用push
,pop
,top
, andgetMin
最多被调用3 * 104
次