Day82(栈,优先级队列)

42、接雨水

给定 n 个非负整数表示每个宽度为 1 的柱子的高度图,计算按此排列的柱子,下雨之后能接多少雨水。

 暴力法

class Solution {
    public int trap(int[] height) {
        int sum=0;
        for(int i=0;i<height.length;i++){
            //第一个柱子和最后一个柱子不接雨水
            if(i==0||i==height.length-1) continue;

            int rHeight=height[i];//记录右边柱子的最高高度
            int lHeight=height[i];//记录左边柱子的最高高度

            for(int r=i+1; r<height.length; r++){
                rHeight=Math.max(rHeight,height[r]);
            }
            
            for(int l=i-1; l>=0;l--){
                lHeight=Math.max(lHeight,height[l]);
            }
             
            int h = Math.min(lHeight, rHeight) - height[i];
            if (h > 0) sum += h;
        }
        return sum;

    }
}

150、逆波兰表达式求值

 思路:

遇到字符串要用equals,不能用== 
token .equals("+")

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        int res;
        for (String token : tokens) {
            if (token .equals("+")|| token .equals("-")|| token .equals("*")||token .equals("/")){
                int a = stack.pop();
                int b = stack.pop();
                switch (token) {
                    case "+":
                        res = b + a;
                        stack.push(res);
                        break;
                    case "-":
                        res = b - a;
                        stack.push(res);
                        break;
                    case "*":
                        res = b * a;
                        stack.push(res);
                        break;
                    case "/":
                        res = b / a;
                        stack.push(res);
                        break;
                    default:
                        break;
                }
            }else{
                stack.push(Integer.parseInt(token));
            }
        }
        int ans=stack.peek();
        return ans;
    }
}

347、前 K 个高频元素

给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。你可以按 任意顺序 返回答案。

优先级队列是不同于先进先出队列的另一种队列。每次从队列中取出的是具有最高优先权的元素。
即:
优先级判断默认输出按数组从高到低顺序。如:入队是5 4 6 3 1 ,那么出队列是6 5 4 3 2 1

优先级队列默认就是一个披着队列外衣的大顶堆,因为优先级队列对外接口只是从队头取元素,从队尾添加元素,再无其他取元素的方式,看起来就是一个队列。而且优先级队列内部元素是自动依照元素的权值排列。

我们要用小顶堆,因为要统计最大前k个元素,只有小顶堆每次将最小的元素弹出,最后小顶堆里积累的才是前k个最大元素。
而使用小顶堆,就要对优先级队列进行重写

//小顶堆
//优先队列的小顶堆是我们进行重写的
PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>
(new Comparator<Map.Entry<Integer, Integer>>() {
    @Override
    public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
           return o1.getValue()-o2.getValue();
    }
});

完整代码 题目要求:

  1. 要统计元素出现频率
  2. 对频率排序
  3. 找出前K个高频元素
class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer,Integer>map=new HashMap<>();//k-v: k:数值 v:频率
        for(int num : nums){
            map.put(num,map.getOrDefault(num,0)+1);
        }

        //小顶堆
        //优先队列是我们自定义的
        PriorityQueue<Map.Entry<Integer, Integer>> queue = new PriorityQueue<>(new Comparator<Map.Entry<Integer, Integer>>() {
            @Override
            public int compare(Map.Entry<Integer, Integer> o1, Map.Entry<Integer, Integer> o2) {
                return o1.getValue()-o2.getValue();
            }
        });

        //依照从小到大的频率次数入队列
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) {
            queue.offer(entry);
            //只留下大小为k的队列长度,这样子k个元素就是输出频率前k的
            if (queue.size() > k) {
                queue.poll();
            }
        }
        
        int res[]=new int[k];
        for (int i=k-1;i>=0;i--){
            res[i]=queue.poll().getKey();
        }
        
        return res;
    }
}

 

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值