代码随想录| 150. 逆波兰表达式求值239. 滑动窗口最大值347.前 K 个高频元素

import java.util.*;

public class Day10 {
    //给你一个字符串数组 tokens ,表示一个根据 逆波兰表示法 表示的算术表达式。
    //请你计算该表达式。返回一个表示表达式值的整数。
    //注意:
    //有效的算符为 '+'、'-'、'*' 和 '/' 。
    //每个操作数(运算对象)都可以是一个整数或者另一个表达式。
    //两个整数之间的除法总是 向零截断 。
    //表达式中不含除零运算。
    //输入是一个根据逆波兰表示法表示的算术表达式。
    //答案及所有中间计算结果可以用 32 位 整数表示。
    public int evalRPN1(String[] tokens) {
        Stack<String> stack=new Stack<>();
        int temp1,temp2;
        for(int i=0;i<tokens.length;i++){
            switch (tokens[i]){
                case "+":
                    temp1=Integer.parseInt(stack.pop());
                    temp2=Integer.parseInt(stack.pop());
                    stack.add(String.valueOf(temp1+temp2));
                    break;
                case "-":
                     temp1=Integer.parseInt(stack.pop());
                     temp2=Integer.parseInt(stack.pop());
                    stack.add(String.valueOf(temp2-temp1));
                    break;
                case "*":
                    temp1=Integer.parseInt(stack.pop());
                    temp2=Integer.parseInt(stack.pop());
                    stack.add(String.valueOf(temp2*temp1));
                    break;
                case "/":
                    temp1=Integer.parseInt(stack.pop());
                    temp2=Integer.parseInt(stack.pop());
                    stack.add(String.valueOf(temp2/temp1));
                    break;
                default:stack.add(tokens[i]);
            }
        }
        return Integer.parseInt(stack.pop());
    }
    public int evalRPN2(String[] tokens) {//一直用Integer.parseInt太麻烦了,直接将栈设置为Integer类型
        Stack<Integer> stack=new Stack<>();
        int temp1,temp2;
        for(int i=0;i<tokens.length;i++){
            switch (tokens[i]){
                case "+":
                    temp1=stack.pop();
                    temp2=stack.pop();
                    stack.add(temp2+temp1);
                    break;
                case "-":
                    temp1=stack.pop();
                    temp2=stack.pop();
                    stack.add(temp2-temp1);
                    break;
                case "*":
                    temp1=stack.pop();
                    temp2=stack.pop();
                    stack.add(temp2*temp1);
                    break;
                case "/":
                    temp1=stack.pop();
                    temp2=stack.pop();
                    stack.add(temp2/temp1);
                    break;
                default:stack.add(Integer.parseInt(tokens[i]));
            }
        }
        return stack.pop();
    }
    //给你一个整数数组 nums,有一个大小为 k 的滑动窗口从数组的最左侧移动到数组的最右侧。
    // 你只可以看到在滑动窗口内的 k 个数字。滑动窗口每次只向右移动一位。
    //返回 滑动窗口中的最大值 。
    
    //思路
//    设计单调队列的时候,pop,和push操作要保持如下规则:
//    pop(value):如果窗口移除的元素value等于单调队列的出口元素,那么队列弹出元素,否则不用任何操作
//    push(value):如果push的元素value大于入口元素的数值,那么就将队列入口的元素弹出,直到push元素的数值小于等于队列入口元素的数值为止
//    保持如上规则,每次窗口移动的时候,只要问que.front()就可以返回当前窗口的最大值。
private  class MyQueue{
        Deque<Integer> deque =new LinkedList<>();
        MyQueue(){

        }
        public void pop(int value){
            if(!deque.isEmpty()&& deque.peek()==value)
                 deque.poll();
        }
        public void push(int value){
            while(!deque.isEmpty()&& deque.getLast()<value){
                deque.removeLast();
            }
            deque.add(value);
        }
        public int getMaxValue(){
                return deque.peek();
        }
    }
    public int[] maxSlidingWindow(int[] nums, int k) {
        MyQueue deque=new MyQueue();
        int[] MaxValue=new int[nums.length-k+1];
        int count=0;
        for(int i=0;i<nums.length;i++){
            deque.push(nums[i]);
            if(i>=k-1) {
                MaxValue[count++]=deque.getMaxValue();
                deque.pop(nums[i-k+1]);
            }
        }
        return MaxValue;
    }
    //给你一个整数数组 nums 和一个整数 k ,请你返回其中出现频率前 k 高的元素。
    // 你可以按 任意顺序 返回答案。
    public int[] topKFrequent(int[] nums, int k) {
        int[] result=new int[k];
        HashMap<Integer,Integer> map=new HashMap<>();
        for (int num : nums) {
            map.put(num, map.getOrDefault(num, 0) + 1);
            //getOrDefault() 方法获取指定 key 对应对 value,如果找不到 key ,则返回设置的默认值。
        }
        PriorityQueue<int[]> pq=new PriorityQueue<>((pair1,pair2)->pair1[1]-pair2[1]);
        for (Map.Entry<Integer, Integer> entry : map.entrySet()) { //小顶堆只需要维持k个元素有序
            if (pq.size() < k) { //小顶堆元素个数小于k个时直接加
                pq.add(new int[]{entry.getKey(), entry.getValue()});
            } else {
                if (entry.getValue() > pq.peek()[1]) { //当前元素出现次数大于小顶堆的根结点(这k个元素中出现次数最少的那个)
                    pq.poll(); //弹出队头(小顶堆的根结点),即把堆里出现次数最少的那个删除,留下的就是出现次数多的了
                    pq.add(new int[]{entry.getKey(), entry.getValue()});
                }
            }
        }
        for(int i=k-1;i>=0;i--){
            result[i]=pq.poll()[0];
        }
        return result;
    }
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值