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 +
。 - 计算过程:
- 遇到操作数时,加入栈中。
- 遇到运算符时,从栈中弹出两个操作数进行计算,并将结果加入栈中。
- 最终栈中剩余的唯一一个值即为表达式的结果。
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;
}
};