DAY11 - 150. 逆波兰表达式求值, 239. 滑动窗口最大值, 347.前 K 个高频元素
150. 逆波兰表达式求值
同样使用栈,碰到数字就入栈,碰到运算符就出栈两个数字进行运算结果,将结果入栈
class Solution {
public:
int evalRPN(vector<string>& tokens) {
stack<int> st;
for(string s:tokens){
if(s=="+"||s=="-"||s=="*"||s=="/"){
int a=st.top();
st.pop();
int b=st.top();
st.pop();
if(s=="+") st.push(a+b);
if(s=="-") st.push(b-a);
if(s=="*") st.push(a*b);
if(s=="/") st.push(b/a);
}else{
st.push(stoi(s));
}
}
return st.top();
}
};
stoi()string to int,stollstring to long
239. 滑动窗口最大值
暴力解法时间复杂度是 n*k,用队列尝试用 O(N) 解决。
单调队列:队列中保证单调递增(递减)
queue和deque
最大区别:deque两端可进出,并且元素可随机访问
容器适配器(queue stack)是不支持迭代器的
class Solution {
private:
class MyQue{
public:
deque<int> que;
void push(int x){
while(!que.empty()&&x>que.back()){
que.pop_back();
}
que.push_back(x);
}
void pop(int x){
if(x==que.front()){
que.pop_front();
}
}
int front(){
return que.front();
}
};
public:
vector<int> maxSlidingWindow(vector<int>& nums, int k) {
MyQue que;
vector<int> res;
// 初始化窗口
for(int i=0;i<k;i++){
que.push(nums[i]);
}
res.push_back(que.front());
for(int i=k;i<nums.size();i++){
que.pop(nums[i-k]);
que.push(nums[i]);
res.push_back(que.front());
}
return res;
}
};
还是有点难度的。而且感觉自定义pop那里是不是有点问题?只比较值的话碰到重复的值是不是就会错误操作?=》想了一下好像不会,因为有重复值说明进来了一个,又出去一个也没问题。
347.前 K 个高频元素
class 和 struct
相同点
-
功能相同:
-
class和struct都可以用来定义一个复合类型(用户自定义类型),其中可以包含成员变量、成员函数、构造函数、析构函数、运算符重载等。 -
它们都可以继承其他类、实现多态、支持模板等。
-
-
语法相似:
- 它们的语法几乎是一样的。比如定义一个成员函数、变量等,在
class和struct中都是相同的。
- 它们的语法几乎是一样的。比如定义一个成员函数、变量等,在
不同点
-
默认的成员访问权限:
-
struct:默认的成员访问权限是public。 -
class:默认的成员访问权限是private。
-
-
使用场景:
struct通常用于简单的数据结构,尤其是在需要公有数据成员并且成员之间没有复杂的封装、继承等特性时。C 语言使用的结构体是struct类型。class通常用于复杂的对象,特别是在面向对象编程中,class用于实现数据封装、继承、多态等特性。
priority_queue
priority_queue<T, Container, Compare> pq;
- T:队列中存储的元素类型。
- Container:底层容器类型,默认是
vector。你也可以指定其他容器类型,比如deque。 - Compare:一个比较函数或函数对象,指定队列中的元素如何排序。默认是大顶堆,要改成小顶堆要重载运算符。
struct mycompare{
bool operator()(const pair<int,int> &a, const pair<int,int> &b){
return a.second > b.second; //注意是大于
}
};
关于unordered_map的查找插入写法
以下两段代码等价
unordered_map<int,int> map;
for(int n:nums){
auto it=map.find(n)
if(it!=map.end()){
it->second++;
}else{
map.insert({n,0});
}
}
简单写法
unordered_map<int, int> map;
for (int n:nums) {
map[n]++; //map会自动处理插入新键值对
}
答案
class Solution {
public:
struct mycompare{
bool operator()(const pair<int,int> &a, const pair<int,int> &b){
return a.second > b.second;
}
};
vector<int> topKFrequent(vector<int>& nums, int k) {
unordered_map<int,int> map;
for(int n:nums){
map[n]++;
}
priority_queue<pair<int,int>, vector<pair<int,int>>, mycompare> pq;
for(auto m:map){
pq.push(m);
if(pq.size()>k){
pq.pop();
}
}
vector<int> res;
while(!pq.empty()){
res.push_back(pq.top().first);
pq.pop();
}
return res;
}
};
- 注意,
vector<int> res(k)这行代码会初始化一个大小为k的vector<int>,其中的每个元素都被默认初始化为 0。所以再res(k)后面再push_back就会导致数组大小大于k,正确的写法是通过索引直接填充而不是用push_back
浙公网安备 33010602011771号