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; } }
代码随想录| 150. 逆波兰表达式求值239. 滑动窗口最大值347.前 K 个高频元素
最新推荐文章于 2024-11-15 18:38:47 发布