Day 11 - Leetcode 239滑动窗口最大值 | Leetcode 347前K个高频元素

java中Deque双端队列

常用的函数补充:

  • getLast()
  • removeLast()
  • addFirst()

leetcode 239

题目链接
滑动窗口最大值

思路:

  • 用优先队列/大顶堆?——不行,每次往后移动的时候,弹出很麻烦
  • ∴ \therefore 用队列
  • 双端队列(单调栈的一个延申),
    • 每次向右移动时,把窗口左端的值从队列左端剔除,把队列右边小于窗口右端的值全部剔除
    • 队列最左端的数始终是窗口内最大的数
    • push(val).push(val)val > > > 队头元素,将队头元素弹出;直到val ≤ \le 队头元素
    • pop(val):如果窗口移除的元素val = = = 单调队列的出口元素,那么队列弹出元素,否则不用任何操作

note: 有点小难,多练几遍!!

class MyDeque {
    Deque<Integer> deque;
    MyDeque() {
        deque = new ArrayDeque<>();
    }
    public void add(int x) {
        while (!deque.isEmpty() && x > deque.getLast())     //decreasing
            deque.removeLast();
        deque.add(x);
    }

    public int peek() {
        return deque.peek();
    }

    public void remove(int x) {
        if (!deque.isEmpty() && x == deque.peek())
            deque.remove();
    }
}
class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        MyDeque myQ = new MyDeque();
        //record the len of the array which should be return
        int len = nums.length - k + 1;  
        int[] res = new int[len];
        int n = 0;

        for (int i = 0; i < k; ++i)
            myQ.add(nums[i]);
        res[n++] = myQ.peek();

        for (int i = k; i < nums.length; ++i) {
            myQ.remove(nums[i - k]);
            myQ.add(nums[i]);
            res[n++] = myQ.peek();
        }
        return res;
    }
}

java 中堆/优先队列

什么是堆?

  • 一棵完全二叉树,树中每个结点的值都不小于(或不大于)其左右孩子的值。 如果父亲结点是大于等于左右孩子就是大顶堆,小于等于左右孩子就是小顶堆。
  • 堆头最大——大顶堆;堆头最小——小顶堆

java中实现

  • java.util.PriorityQueue<>:优先队列
    • 默认是小根堆,大根堆写法:new PriorityQueue<>(Collections.reverseOrder())

定义及初始化

Queue<Integer> q1 = new PriorityQueue<Integer>();   //优先队列,默认小根堆(从小到大)
Queue<Integer> q2 = new PriorityQueue<Integer>(Collections.reverseOrder()); //大根堆


leetcode 347

题目链接
前K个高频元素

思路:

  • 小/大顶堆,优先队列
  • map先来记录每个数的出现频次
  • 再用优先队列完成排序

大根堆代码示例如下(主要看PriorityQueue定义!!!)

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        //统计frequence
        for (int i = 0; i < nums.length; ++i)
            map.put(nums[i], map.getOrDefault(nums[i], 0) + 1);

        // 大根堆
        Queue<int[]> queue = new PriorityQueue<>((x, y) -> {
            return y[1] - x[1];
        });
        for (Map.Entry<Integer, Integer> x : map.entrySet()) {
            int[] temp = {x.getKey(), x.getValue()};
            queue.add(temp);
        }

        int[] res = new int[k];
        for (int i = 0; i < k; ++i)
            res[i] = queue.remove()[0];
        return res;
    }
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值