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

32 阅读2分钟

150. 逆波兰表达式求值

题目:150. 逆波兰表达式求值 - 力扣(LeetCode)

题解:代码随想录

状态:AC

思路

利用栈的性质即可解决,但要注意判断字符串相等时需要用equals

代码

时间复杂度:O(n) 空间复杂度:O(n)

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for(int i = 0; i < tokens.length; i++){
            if(tokens[i].equals("+")){
                stack.push(stack.pop() + stack.pop());
            }else if(tokens[i].equals("-")){
                stack.push(- stack.pop() + stack.pop());
            }else if(tokens[i].equals("*")){
                stack.push(stack.pop() * stack.pop());
            }else if(tokens[i].equals("/")){
                int a = stack.pop(), b = stack.pop();
                stack.push(b / a);
            }else{
                stack.push(Integer.parseInt(tokens[i]));
            }
        }
        return stack.pop();
    }
}

239. 滑动窗口最大值

题目:239. 滑动窗口最大值 - 力扣(LeetCode)

题解:代码随想录

状态:需要多复习

思路

单调队列

  • 一个双端队列,当新加入元素比队尾元素大时,循环移除队尾元素直到没有比新入元素大的元素为止;
  • 之后新元素索引入队;
  • 判断当前队头元素是否超出队列大小限制(K),超出则移除队头;
  • 期间用一个idx索引中间变量记录res数组索引位置,当队列首次达到k后开始将结果放入res数组

代码

时间复杂度:O(n) 空间复杂度:O(n)

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int[] res = new int[nums.length - k + 1];
        int idx = 0;
        Deque<Integer> q = new LinkedList<>();
        for(int i = 0; i < nums.length; i++){
            while(!q.isEmpty() && nums[i] >= nums[q.getLast()]){
                q.removeLast();
            }
            q.offer(i);
            if(i - q.peek() >= k){
                q.poll();
            }
            if(i >= k - 1){
                res[idx++] = nums[q.peek()];
            }
        }
        return res;
    }
}

347.前 K 个高频元素

题目:347. 前 K 个高频元素 - 力扣(LeetCode)

题解:代码随想录

状态:需要多复习

思路

优先队列

  • 维护一个大小为k的小顶堆,当加入的元素比队头大时就移除队头
  • 最后队列中剩下的元素就是答案

代码

时间复杂度:O(nlogn) 空间复杂度:O(n)

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

        PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2) -> pair1[1] - pair2[1]);
        for(var entry : map.entrySet()){
            if(pq.size() < k){
                pq.add(new int[]{entry.getKey(), entry.getValue()});
            } else{
                if(entry.getValue() > pq.peek()[1]){
                    pq.poll();
                    pq.add(new int[]{entry.getKey(), entry.getValue()});
                }
            }
        }
        int[] ans = new int[k];
        for(int i = k - 1; i >= 0; i--){
            ans[i] = pq.poll()[0];
        }
        return ans;
    }
}