leetcode-239:滑动窗口最大值

简介: leetcode-239:滑动窗口最大值

题目

题目链接

给你一个整数数组 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]

示例 3:

输入:nums = [1,-1], k = 1
输出:[1,-1]

示例 4:

输入:nums = [9,11], k = 2
输出:[11]

示例 5:

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

解答

方法一:利用单调队列

1.利用双端队列记录当前滑动窗口的元素索引

2.队列最左侧元素记录滑动窗口中最大元素的索引

3.遍历数组:

  • 如果队列最左侧索引已不在滑动窗口范围内,弹出队列最左侧索引
  • 通过循环确保队列的最左侧索引所对应元素值最大
  • 新元素入队
  • 从第一个滑动窗口的末尾索引开始将最大值存储到结果res中

图片来源

python写法

class Solution:
    def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
        res = []
        queue = collections.deque()
        for i,num in enumerate(nums):
            if queue and queue[0]==i-k:#比如上图中,4对应的i=4,k=5,那么i-k=-1  。如果右侧滑到8,那么i-k=0,也就是说2要被去除.
                queue.popleft()
            while queue and nums[queue[-1]]<num:
                queue.pop()
            queue.append(i)
            if i>=k-1:
                res.append(nums[queue[0]])
        return res

c++写法

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> res;
        deque<int> deque;
        for(int i=0;i<nums.size();i++){
            if(!deque.empty()&&deque.front()==i-k){
                deque.pop_front();
            }
            while(!deque.empty()&&nums[deque.back()]<nums[i]){
                deque.pop_back();
            }
            deque.push_back(i);
            if(i>=k-1){
                res.push_back(nums[deque.front()]);
            }
        }
        return res;
    }
};

java写法

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        LinkedList<Integer> deque=new LinkedList<>();
        int[] res=new int[nums.length-k+1];
        for(int i=0;i<nums.length;i++){
            if(!deque.isEmpty()&&deque.peek()==i-k){
                deque.poll();
            }
            while(!deque.isEmpty()&&nums[deque.peekLast()]<=nums[i]){
                deque.pollLast();
            }
            deque.addLast(i);
            if(i>=k-1){
                res[i-k+1]=nums[deque.peek()];
            }
        }
        return res;
    }
}

LinkedList

头部添加addFirst()、尾部添加addLast();

头部删除pollFirst()、尾部删除pollLast()

取头部值peekFirst()、取尾部值peekLast()

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {  
        int n=nums.length;
        int[] res=new int[n-k+1];
        LinkedList<Integer> deque= new LinkedList<>();
        for(int i=0;i<n;i++){
            if(!deque.isEmpty()&&i-k==deque.peekFirst()){
                deque.pollFirst();
            }
            while(!deque.isEmpty()&&nums[i]>=nums[deque.peekLast()]){
                deque.pollLast();
            }
            deque.addLast(i);
            if(i-k+1>=0){
                res[i-k+1]=nums[deque.peekFirst()];
            }
        }
        return res;
    }
}


相关文章
|
8月前
|
存储 算法
LeetCode刷题---209. 长度最小的子数组(双指针-滑动窗口)
LeetCode刷题---209. 长度最小的子数组(双指针-滑动窗口)
|
3月前
【LeetCode 26】239.滑动窗口最大值
【LeetCode 26】239.滑动窗口最大值
44 1
|
3月前
【LeetCode 04】滑动窗口法总结
【LeetCode 04】滑动窗口法总结
32 0
|
5月前
|
存储 Python
【Leetcode刷题Python】239. 滑动窗口最大值
文章介绍了两种解决LeetCode上"滑动窗口最大值"问题的方法:使用大堆树和双向递减队列,提供了详细的解析和Python代码实现。
45 0
|
7月前
|
算法 搜索推荐
力扣每日一题 6/15 滑动窗口
力扣每日一题 6/15 滑动窗口
41 1
|
7月前
|
算法
【LeetCode刷题】滑动窗口解决问题:串联所有单词的子串(困难)、最小覆盖子串(困难)
【LeetCode刷题】滑动窗口解决问题:串联所有单词的子串(困难)、最小覆盖子串(困难)
|
7月前
|
算法 容器
【LeetCode刷题】滑动窗口解决问题:水果成篮、找到字符串中所有字母异位词
【LeetCode刷题】滑动窗口解决问题:水果成篮、找到字符串中所有字母异位词
|
6月前
|
存储 算法
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
经典的滑动窗口的题目 力扣 2799. 统计完全子数组的数目(面试题)
|
7月前
|
算法 索引
力扣随机一题 位运算/滑动窗口/数组
力扣随机一题 位运算/滑动窗口/数组
55 0
|
7月前
【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数
【LeetCode刷题】滑动窗口思想解决:最大连续1的个数 III、将x减到0的最小操作数