0
点赞
收藏
分享

微信扫一扫

Java 中的队列、堆、栈

山竹山竹px 2022-03-30 阅读 104
javaleetcode

引入

做LeetCode题目:滑动窗口最大值
给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。返回 滑动窗口中的最大值 。https://leetcode-cn.com/problems/sliding-window-maximum
历时几个星期,用自己朴素的想法,解题都对,但是超时间。在这里插入图片描述
查看题解,要用到一些队里的知识。特此在本文记录一下这方面的知识。队列,堆栈的使用,推荐就使用Java封装好的类,去使用就好,否则自己来写,往往一头雾水,还没有效率,我们就大胆的站在巨人的肩膀上,直接使用这些底层类,而不用去管底层的实现。如果每次纠结,想自己来实现,真的是一言难尽啊

单词学习

添加元素删除头顶元素读头顶元素
addremoveelement
offerpollpeek
pushpopfirst

peek 的意思有瞥见
poll 头顶的意思
https://blog.csdn.net/devnn/article/details/82716447

使用示例

一、优先队列

    // 优先队列 (堆)
	PriorityQueue<Object> priorityQueue = new PriorityQueue<Object>(new Comparator<Object>() {
        // 重写比较方法,怎么判断优先
		public int compare(Object pair1, Object pair2) {
            return pair1[0] != pair2[0] ? pair2[0] - pair1[0] : pair2[1] - pair1[1];
        }
    });
	priorityQueue.offer(new int[]{nums[i], i}); // 添加
	priorityQueue.peek()[0]; // 查看头顶元素
	priorityQueue.poll(); // 删除头顶元素

原文连接题解:

public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        PriorityQueue<int[]> priorityQueue = new PriorityQueue<int[]>(new Comparator<int[]>() {
            public int compare(int[] pair1, int[] pair2) {
                return pair1[0] != pair2[0] ? pair2[0] - pair1[0] : pair2[1] - pair1[1];
            }
        });
        for (int i = 0; i < k; ++i) {
            priorityQueue.offer(new int[]{nums[i], i});
        }
        int[] ans = new int[n - k + 1];
        ans[0] = priorityQueue.peek()[0];
        for (int i = k; i < n; ++i) {
            priorityQueue.offer(new int[]{nums[i], i});
            while (priorityQueue.peek()[1] <= i - k) {
                priorityQueue.poll();
            }
            ans[i - k + 1] = priorityQueue.peek()[0];
        }
        return ans;
    }

二、单调队列
Deque deque = new LinkedList(); // 记录最大值的下标
deque.offerLast();
deque.isEmpty();
deque.peekLast();
deque.pollLast();

// 单调队列,单调递减的队列,头上的是最大的
    public int[] maxSlidingWindow(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;
    }

三、稀疏表(Sparse Table)求区间最值问题
预处理
递推
prefixMax[i] 从0到i之间的最大值
suffixMax[i] 从i 到 length的最大值
那么 Max[i] = max{ prefixMax[i] ,suffixMax[i]}

举报

相关推荐

0 条评论