算法day10-栈与队列(2)

目录

  1. 逆波兰表达式求值
  2. 滑动窗口最大值
  3. 前K个高频元素

一、逆波兰表达式求值

  https://leetcode.cn/problems/evaluate-reverse-polish-notation/description/?envType=problem-list-v2&envId=8At1GmaZ

 

class Solution {
    public int evalRPN(String[] tokens) {
        Deque<String> stack = new ArrayDeque<>();
        for(String s : tokens){
            if(s.equals("+")){
                int n2 = Integer.parseInt(stack.pop());
                int n1 = Integer.parseInt(stack.pop());
                int sum = n2 + n1;
                stack.push(String.valueOf(sum));
            }else if(s.equals("-")){
                int n2 = Integer.parseInt(stack.pop());
                int n1 = Integer.parseInt(stack.pop());
                int n = n1 - n2;
                stack.push(String.valueOf(n));
            }else if(s.equals("*")){
                int n2 = Integer.parseInt(stack.pop());
                int n1 = Integer.parseInt(stack.pop());
                int n = n1 * n2;
                stack.push(String.valueOf(n));
            }else if(s.equals("/")){
                int n2 = Integer.parseInt(stack.pop());
                int n1 = Integer.parseInt(stack.pop());
                int n = n1 / n2;
                stack.push(String.valueOf(n));
            }else{
                stack.push(s);
            }
        }
        return Integer.parseInt(stack.pop());
    }
}

二、滑动窗口最大值

  https://leetcode.cn/problems/sliding-window-maximum/description/?envType=problem-list-v2&envId=8At1GmaZ

   方法一:暴力法,直接以3为窗口进行滑动,在每个窗口内都取最大值。

  方法二:采用单调队列的方法,始终维护一个单调队列。每个窗口都把最大的元素放在队头,所以每次弹出的也是队头元素,这样可以利用到前面窗口的信息。

class Solution {
    public int[] maxSlidingWindow(int[] nums, int k) {
        int n = nums.length;
        int[] res = new int[n-k+1];
        Deque<Integer> queue = new ArrayDeque<>();
        int index = 0;
        
        for(int i = 0; i<n; i++){
            //1.新入队的元素若头节点的索引已经超过以i结尾的窗口的起点,就把头节点去掉
            if(!queue.isEmpty() && queue.peek() < i-k+1){
                queue.poll();       //把头节点从队头剔除
            }
            while(!queue.isEmpty() && nums[queue.peekLast()] < nums[i]){
                queue.pollLast();           //把比新加入的元素小的元素从末尾剔除
            }
            queue.offer(i);
            if(i >= k-1){
                res[index] = nums[queue.peek()];
                index++;
            }
        }
        return res;
    }
}
//时间复杂度:O(N)
//空间复杂度:O(k)

 

三、前k个高频元素

  https://leetcode.cn/problems/top-k-frequent-elements/description/?envType=problem-list-v2&envId=8At1GmaZ

 

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[]> queue = new PriorityQueue<>((pair1, pair2)->pair2[1] - pair1[1]);
        //遍历哈希表,把对应的k-v存储到队列中
        for(Map.Entry<Integer,Integer> entry : map.entrySet()){
            queue.add(new int[]{entry.getKey(), entry.getValue()});
        }

        int[] res = new int[k];
        for(int i=0; i<k; i++){
            res[i] = queue.poll()[0];       //把key弹出来
        }
        return res;
    }
}
//时间复杂度: O(nlogk)
//空间复杂度: O(n)

 【扩展】数组重的第K个最大元素

  https://leetcode.cn/problems/kth-largest-element-in-an-array/description/?envType=problem-list-v2&envId=SrjwzI6W

   这道题我们用堆排序来做,主要是熟悉堆排序的流程。

 

class Solution {
    public int findKthLargest(int[] nums, int k) {

        int n = nums.length;
        int heapSize = n;

        for(int i = n / 2 - 1; i >= 0; i--){
            maxHeapify(nums, i, heapSize);
        }

        for(int i = n - 1; i >= n - k + 1; i--){
            swap(nums, 0, i);
            heapSize--;
            maxHeapify(nums, 0, heapSize);
        }

        return nums[0];
    }

    public void maxHeapify(int[] nums, int root, int heapSize){
        int left = root * 2 + 1, right = root * 2 + 2;
        int largest = root;
        if(left < heapSize && nums[left] > nums[largest]){
            largest = left;
        }
        if(right < heapSize && nums[right] > nums[largest]){
            largest = right;
        }

        if(largest != root){
            swap(nums, root, largest);
            maxHeapify(nums, largest, heapSize);
        }
    }

    public void swap(int[] nums, int i, int j){
        int temp = nums[i];
        nums[i] = nums[j];
        nums[j] = temp;
    }
}

 

posted @ 2025-05-05 13:47  筱倩  阅读(227)  评论(0)    收藏  举报