程式碼隨想錄刷題day 11 | **150. 逆波蘭表示式求值** **239. 滑動視窗最大值** **347.前 K 個高頻元素**

12点不睡觉还想干啥?發表於2024-07-14

[150. 逆波蘭表示式求值](https://leetcode.cn/problems/reverse-string/)

使用棧即可,遍歷token陣列,遇到運算子就彈棧,取出兩個數做運算然後壓棧。遇到數字就壓棧。最終棧中剩餘的唯一數字就是結果。

class Solution {
    public int evalRPN(String[] tokens) {
        Stack<Integer> stack = new Stack<>();
        for(String s: tokens){
            if(s.equals("+") || s.equals("-") || s.equals("*") || s.equals("/")) {
                int num2 = stack.pop();
                int num1 = stack.pop();
                if(s.equals("+")) stack.push(num1 + num2);
                if(s.equals("-")) stack.push(num1 - num2);
                if(s.equals("*")) stack.push(num1 * num2);
                if(s.equals("/")) stack.push(num1 / num2);
            }else{
                stack.push(Integer.parseInt(s));
            }
        }
        return stack.peek();
    }
}

239. 滑動視窗最大值

這裡先給出Java中雙端佇列Deque的用法 https://blog.csdn.net/weixin_47772522/article/details/132342631

剩餘的看註釋即可

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        MyQueue queue = new MyQueue();
        for(int i = 0; i < k; i++) queue.push(nums[i]);
        int[] res = new int[nums.length - k + 1];
        res[0] = queue.peek();
        for(int i = 0; i < res.length - 1; i++){
            queue.offer(nums[i]); //移除視窗左端的元素
            queue.poll(nums[i+k]); //移入右端元素
            res[i+1] = queue.peek();
        }
        return res;
    }
}
class MyQueue{
    Deque<Integer> queue;
    public MyQueue(){
        this.queue = new LinkedList<>();
    }
    public void offer(int x){  //在佇列尾部插入元素(對於本題,插入視窗移動後最右端的元素) 命名儘量遵守佇列的介面 offer/add代表新增元素 poll
        while(this.queue.peekLast() != null && this.queue.peekLast() < x) this.queue.pollLast();
        this.queue.offerLast(x);
    }
    public void poll(int x){  //在佇列頭刪除元素,對於本題,意味著視窗向右挪動後,移除佇列中對應於移出視窗的那個元素
        if(this.queue.peekFirst() == x) this.queue.removeFirst();
    }
    public int peek(){
        return this.queue.peekFirst();
    }
}

347. 前 K 個高頻元素

最主要的還是map的遍歷以及優先佇列的用法,這個和堆排序的思想很像。

class Solution {
    public int[] topKFrequent(int[] nums, int k) {
        Map<Integer, Integer> map = new HashMap<>();
        for(int num: nums){
            map.put(num, map.getOrDefault(num, 0)+1);
        }
        PriorityQueue<int[]> pq = new PriorityQueue<>((pair1, pair2)-> pair1[1] - pair2[1]);  //前減後代表小頂堆
        for(Map.Entry<Integer, Integer> entry: map.entrySet()){
            pq.offer(new int[]{entry.getKey(), entry.getValue()});
            if(pq.size() > k) pq.poll();
        }
        int[] res = new int[k];
        for(int i = k - 1; i >= 0; i--){
            res[i] = pq.poll()[0];
        }
        return res;
    }
}

相關文章