算法之滑动窗口

力扣239

package com.zhang.reflection.面试.算法模版.滑动窗口;
import java.util.Deque;
import java.util.LinkedList;
import java.util.PriorityQueue;
/**
 * 给你一个整数数组 nums,有一个大小为k的滑动窗口从数组的最左侧移动到数组的最右侧。
 * 你只可以看到在滑动窗口内的 k个数字。滑动窗口每次只向右移动一位。
 *
 * 返回 滑动窗口中的最大值 。
 *
 */
public class 滑动窗口最大值 {
    /**
     * 解法一:使用优先队列
     * 对于「最大值」,我们可以想到一种非常合适的数据结构,那就是优先队列(堆),其中的大根堆可以帮助我们实时维护一系列元素中的最大值。
     *
     * 对于本题而言,初始时,我们将数组 \textit{nums}nums 的前 kk 个元素放入优先队列中。
     * 每当我们向右移动窗口时,我们就可以把一个新的元素放入优先队列中,此时堆顶的元素就是堆中所有元素的最大值。然而这个最大值可能并不在滑动窗口中,
     * 在这种情况下,这个值在数组 \textit{nums}nums 中的位置出现在滑动窗口左边界的左侧。因此,当我们后续继续向右移动窗口时,
     * 这个值就永远不可能出现在滑动窗口中了,我们可以将其永久地从优先队列中移除。
     *
     * 我们不断地移除堆顶的元素,直到其确实出现在滑动窗口中。此时,堆顶元素就是滑动窗口中的最大值。
     * 为了方便判断堆顶元素与滑动窗口的位置关系,我们可以在优先队列中存储二元组 (\textit{num}, \textit{index})(num,index),
     * 表示元素 \textit{num}num 在数组中的下标为 \textit{index}index。
     */
    public int[] maxSlidingWindow(int[] nums, int k) {
        PriorityQueue<int[]> heap=new PriorityQueue<int[]>((a, b)->a[0]==b[0]?b[1]-a[1]:b[0]-a[0]);
        for(int i=0;i<k;i++){
            heap.offer(new int[]{nums[i],i});
        }
        int[] result=new int[nums.length-k+1];
        result[0]=heap.peek()[0];
        for(int i=k;i<nums.length;i++){
            heap.offer(new int[]{nums[i],i});
            while(heap.peek()[1]<=i-k){
                heap.poll();
            }
            result[i-k+1]=heap.peek()[0];
        }
        return result;
    }

    /**
     * 解法二:单调队列
     * https://leetcode-cn.com/problems/sliding-window-maximum/solution/hua-dong-chuang-kou-zui-da-zhi-by-leetco-ki6m/
     */
    public int[] maxSlidingWindow1(int[] nums, int k) {
        int n = nums.length;
        Deque<Integer> deque = new LinkedList<Integer>();
        for (int i = 0; i < k; ++i) {
            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
                deque.pollLast();
            }
            deque.offerLast(i);
        }

        int[] ans = new int[n - k + 1];
        ans[0] = nums[deque.peekFirst()];
        for (int i = k; i < n; ++i) {
            while (!deque.isEmpty() && nums[i] >= nums[deque.peekLast()]) {
                deque.pollLast();
            }
            deque.offerLast(i);
            while (deque.peekFirst() <= i - k) {
                deque.pollFirst();
            }
            ans[i - k + 1] = nums[deque.peekFirst()];
        }
        return ans;
    }
}
全部评论

相关推荐

oppo 应用软开 22*15+0.5*12
拿到了ssp完美:真的坎坷,但是你至少拿到这么多offer了!
点赞 评论 收藏
分享
点赞 评论 收藏
分享
实习挂完提前批挂_提前批挂完秋招挂:我是来结束这个秋招的😤
点赞 评论 收藏
分享
评论
点赞
收藏
分享
正在热议
# 25届秋招总结 #
440737次浏览 4493人参与
# 春招别灰心,我们一人来一句鼓励 #
41503次浏览 524人参与
# 阿里云管培生offer #
119898次浏览 2219人参与
# 地方国企笔面经互助 #
7930次浏览 18人参与
# 同bg的你秋招战况如何? #
75684次浏览 552人参与
# 虾皮求职进展汇总 #
114355次浏览 884人参与
# 北方华创开奖 #
107318次浏览 599人参与
# 实习,投递多份简历没人回复怎么办 #
2454094次浏览 34848人参与
# 实习必须要去大厂吗? #
55687次浏览 960人参与
# 提前批简历挂麻了怎么办 #
149836次浏览 1977人参与
# 投递实习岗位前的准备 #
1195731次浏览 18546人参与
# 你投递的公司有几家约面了? #
33181次浏览 188人参与
# 双非本科求职如何逆袭 #
661934次浏览 7394人参与
# 如果公司给你放一天假,你会怎么度过? #
4734次浏览 55人参与
# 机械人春招想让哪家公司来捞你? #
157604次浏览 2267人参与
# 如果你有一天可以担任公司的CEO,你会做哪三件事? #
11381次浏览 271人参与
# 发工资后,你做的第一件事是什么 #
12431次浏览 61人参与
# 工作中,努力重要还是选择重要? #
35621次浏览 384人参与
# 参加完秋招的机械人,还参加春招吗? #
20091次浏览 240人参与
# 我的上岸简历长这样 #
451933次浏览 8088人参与
# 实习想申请秋招offer,能不能argue薪资 #
39241次浏览 314人参与
# 非技术岗是怎么找实习的 #
155852次浏览 2120人参与
牛客网
牛客企业服务