leetcode-10-[150]逆波兰表达式求值 [239]滑动窗口最大值[347]前k个高频元素

一、[150]逆波兰表达式求值

重点:逆波兰表示法转中缀表达式时,

“-”、“/”,第二个弹出的元素  “-”  第一个弹出的元素

class Solution {
    public int evalRPN(String[] tokens) {
        //栈内存Integer,比存String好一些,省去了类型转换
        LinkedList<Integer> stack=new LinkedList<>();
        for(int i=0;i< tokens.length;i++){
            String s=tokens[i];
            if("+".equals(s)){
                stack.push(stack.pop()+stack.pop());
            }else if("-".equals(s)){
                int s1=stack.pop();
                int s2=stack.pop();
                stack.push(s2-s1);
            } else if ("*".equals(s)) {
                stack.push(stack.pop()*stack.pop());
            } else if ("/".equals(s)) {
                //注意,弹出的第二个数/弹出的第一个数
                int s1=stack.pop();
                int s2=stack.pop();
                stack.push(s2/s1);
            }else{
                stack.push(Integer.parseInt(s));
            }
        }
        return stack.pop();
    }
}

二、[239]滑动窗口最大值

重点:单调队列 双端队列

1、存储的为数组下标

2、需要保证队列元素在[i+1-k,i]区间,即当队头元素不在这个区间内,及时移出

3、加入的元素值必须小于队尾元素的值(始终保证队头元素最大),否则移出队尾元素,直到满足该条件

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        //单调队列 双端队列
        //存储下标
        Deque<Integer> queue=new ArrayDeque<>();
        int[] res=new int[nums.length-k+1];
        int resId=0;
        for(int i=0;i< nums.length;i++){
            //[i+1-k,i]
            while(!queue.isEmpty()&&queue.peekFirst()<i-k+1){
                queue.pollFirst();
            }
            while(!queue.isEmpty()&&nums[i]>nums[queue.peekLast()]){
                //弹出队尾元素
                queue.pollLast();
            }
            queue.offer(i);
            if(i+1>=k){
                res[resId++]=nums[queue.peekFirst()];
            }
        }
        return res;
    }
}

三、[347]前k个高频元素

重点:小顶堆

Comparator接口说明:
返回负数,形参中第一个参数排在前面;返回正数,形参中第二个参数排在前面

 对于队列:排在前面意味着往队头靠
对于堆(使用PriorityQueue实现):从队头到队尾按从小到大排就是最小堆(小顶堆),
从队头到队尾按从大到小排就是最大堆(大顶堆)--->队头元素相当于堆的根节点

PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]);

第一个参数:1 第二个参数:3    负数    1、3
第一个参数:4 第二个参数:3    正数    3、4
小顶堆

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        /*Comparator接口说明:
         * 返回负数,形参中第一个参数排在前面;返回正数,形参中第二个参数排在前面
         * 对于队列:排在前面意味着往队头靠
         * 对于堆(使用PriorityQueue实现):从队头到队尾按从小到大排就是最小堆(小顶堆),
         * 从队头到队尾按从大到小排就是最大堆(大顶堆)--->队头元素相当于堆的根节点
         * PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]);
         *
         * 第一个参数:1 第二个参数:3   负数   1、3
         * 第一个参数:4 第二个参数:3   正数   3、4
         * 小顶堆
         * */
        //小顶堆
        PriorityQueue<int[]> pq = new PriorityQueue<>((o1, o2) -> o1[1] - o2[1]);
        int[] res=new int[k];
        HashMap<Integer,Integer> map=new HashMap<>();
        for(int i:nums){
            map.put(i,map.getOrDefault(i,0)+1);
        }
        for(var x:map.entrySet()){
            int[] tmp=new int[2];
            tmp[0]=x.getKey();
            tmp[1]=x.getValue();
            pq.offer(tmp);

            //小顶堆
            while(pq.size()>k){
                pq.poll();
            }
        }
        int id=0;
        while(!pq.isEmpty()){
            int[] poll = pq.poll();
            res[id++]=poll[0];
        }
        return res;
    }
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值