leetcode stack and queue, leetcode 347/150/239

347. Top K Frequent Elements

Given an integer array nums and an integer k, return the k most frequent elements. You may return the answer in any order.

Example 1:

Input: nums = [1,1,1,2,2,3], k = 2
Output: [1,2]

Example 2:

Input: nums = [1], k = 1
Output: [1]

思路和实现:

目标
给定一个整数数组 nums 和一个整数 k,返回 k 个出现频率最高的元素。

步骤
统计频率:

首先,遍历数组 nums,使用 unordered_map 统计每个元素出现的频率。
维护一个最小堆:

创建一个最小堆(min heap),用于存储频率最高的 k 个元素。
在 C++ 中,优先队列(priority queue)默认是最大堆,因此我们需要自定义比较函数,将其转换为最小堆。
构建最小堆:

遍历 unordered_map 中的频率对,每次将当前元素的频率推入优先队列中。
如果优先队列的大小超过 k,则弹出堆顶元素,以确保优先队列中始终只包含频率最高的 k 个元素。
提取结果:

将最小堆中的元素提取出来,放入结果向量中并返回。

class Solution {
    class ComparePair {
    public:
        bool operator()(pair<int, int>& p1, pair<int, int>& p2) {
            return p1.second > p2.second;
        }
    };
public:
    vector<int> topKFrequent(vector<int>& nums, int k) {
        unordered_map<int, int> mymap;//collect frequency
        //create a min heap
        priority_queue<pair<int, int>, vector<pair<int, int>>, ComparePair > pri_que;
        for (auto i : nums) {
            mymap[i]++;
        }
        for (auto p : mymap) {
            pri_que.push(p);
            if (pri_que.size() > k) {
                pri_que.pop();
            }
        }
        vector<int> sol;
        while (!pri_que.empty()) {
            int i = pri_que.top().first;
            pri_que.pop();
            sol.push_back(i);
        }
        return sol;

    }
};

150. Evaluate Reverse Polish Notation

You are given an array of strings tokens that represents an arithmetic expression in a Reverse Polish Notation.

Evaluate the expression. Return an integer that represents the value of the expression.

Note that:

  • The valid operators are '+''-''*', and '/'.
  • Each operand may be an integer or another expression.
  • The division between two integers always truncates toward zero.
  • There will not be any division by zero.
  • The input represents a valid arithmetic expression in a reverse polish notation.
  • The answer and all the intermediate calculations can be represented in a 32-bit integer.

Example 1:

Input: tokens = ["2","1","+","3","*"]
Output: 9
Explanation: ((2 + 1) * 3) = 9
  • 逆波兰表示法:一种后缀表示法,运算符放在操作数之后。例如,表达式 2 + 1 在 RPN 中表示为 2 1 +
  • 计算过程
    1. 遇到操作数时,加入栈中。
    2. 遇到运算符时,从栈中弹出两个操作数进行计算,并将结果加入栈中。
    3. 最终栈中剩余的唯一一个值即为表达式的结果。
class Solution {
public:
    int evalRPN(vector<string>& tokens) {
        stack<int> myStack;
        for (auto s : tokens) {
            if (s == "+" || s == "-" || s == "*" || s == "/") {
                int num1 = myStack.top();
                myStack.pop();
                int num2 = myStack.top();
                myStack.pop();
                if (s == "+") {
                    myStack.push(num2 + num1);
                }
                if (s == "-") {
                    myStack.push(num2 - num1);
                }
                if (s == "*") {
                    myStack.push(num2 * num1);
                }
                if (s == "/") {
                    myStack.push(num2 / num1);
                }
            }
            else {
                int i = stoi(s);
                myStack.push(i);//push the integer into stack
            }
        }
        return myStack.top();
    }
};

You are given an array of integers nums, there is a sliding window of size k which is moving from the very left of the array to the very right. You can only see the k numbers in the window. Each time the sliding window moves right by one position.

Return the max sliding window.

Example 1:

Input: nums = [1,3,-1,-3,5,3,6,7], k = 3
Output: [3,3,5,5,6,7]
Explanation: 
Window position                Max
---------------               -----
[1  3  -1] -3  5  3  6  7       3
 1 [3  -1  -3] 5  3  6  7       3
 1  3 [-1  -3  5] 3  6  7       5
 1  3  -1 [-3  5  3] 6  7       5
 1  3  -1  -3 [5  3  6] 7       6
 1  3  -1  -3  5 [3  6  7]      7

Example 2:

Input: nums = [1], k = 1
Output: [1]

//总结:这道题的思路是用deque来存储index,然后遍历nums,如果deque不为空,且deque.front() <= i - k, pop_front,这里是为了保证deque里面的index都在k的范围内
//然后,如果deque不为空,且nums[deque.back()] < nums[i], pop_back,这里是为了保证deque里面的index对应的nums是递减的,需注意判段语句是while而不是if因为可能有多个nums[deque.back()] < nums[i]
//最后,push_back(i)进去,如果i >= k - 1, push_back(nums[deque.front()])进去
//这里的deque.front()就是当前window的最大值,收集到sol里面

class Solution {
public:
    vector<int> maxSlidingWindow(vector<int>& nums, int k) {
        vector<int> sol;
        deque<int> descend;
        for (int i = 0; i < nums.size(); i++) {
            if (!descend.empty() && descend.front() <= i - k) {
                descend.pop_front();
            }
            while (!descend.empty() && nums[descend.back()] < nums[i]) {
                descend.pop_back();
            }
            descend.push_back(i);
            if (i >= k - 1) {
                sol.push_back(nums[descend.front()]);
            }
        }
        return sol;
    }
};

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值