1、需要记住字符串转换成数字的函数 stoi与stoll
2、在滑动窗口最大值中,需要着重体会如何获取窗口中的最大值的减枝行为
3、在前k个高频元素中、
(1)知道堆是通过优先队列priority_queue创建的(默认大根堆)
priority_queue> que;
(2)需要使用重载运算符,需要知道重载运算符的写法
//定义结构体
struct greater2{
//定义比较函数
bool operator()(const 类型&变量a,congst 类型&变量b)
{
return 变量a>变量b;
}
}
priority_queue,vector>,greater2> que;
题目链接:LeetCode150、逆波兰表达式求值
因为在字符串中,只有遇到符号才会让符号前边的两个数使用符号做运算:
所以可以使用栈的先进后出特性,当遇到符号,弹出栈顶两个元素,运算完成输入到栈顶。
难点:
给的是字符串,但是需要使用的是具体的整数进行运算,所以需要将string类型的字符转换成整数,使用:
stoi-->将字符串转换成整型,如果存在不是数字的位置(或者超出int),会抛出异常
stoll-->转换成longlong类型
class Solution {
public:
int evalRPN(vector& tokens) {
//整体使用一个栈记录数字,当出现运算符,弹出栈顶两个值进行运算,运算完成将值填入栈顶
//注意是字符串,需要转换成数字
stack stk;
//注意是32位整数
long long num1=0,num2=0,res=0;
for(auto i : tokens)
{
if(i=="+"||i=="-"||i=="*"||i=="/")
{
num2=stk.top();
stk.pop();
num1 = stk.top();
stk.pop();
if(i=="+")res = num1+num2;
if(i=="-")res = num1-num2;
if(i=="*")res = num1*num2;
if(i=="/")res = num1/num2;
stk.push(res);
}
else stk.push(stoi(i));//存入的是数字
}
return stk.top();
}
};
题目链接:LeetCode239、滑动窗口最大值
滑动窗口-->使用一个双端队列来记录窗口元素的下标
1、遍历字符串时,有新的元素要加入到窗口时:
(1)判断当前窗口的大小,如果加入后窗口已经超过了k,需要让窗口左端向右移动
(2)判断当前元素与窗口中最右端的元素大小,如果当前元素大于窗口最右端的元素,说明在窗口移动过程中还存在当前最右端的元素时,窗口中最大的元素一定不可能是窗口最右端的元素-->可以从窗口中从右向左判断是不是比当前元素大(需要保证双端队列不为空)-->最终窗口中会从左向右递减的状态
(3)将当前的元素下标添加到双端队列
2、遍历字符串时,如果刚开始窗口大小还没有到达k,不能输出窗口的最大元素
class Solution {
public:
vector maxSlidingWindow(vector& nums, int k) {
//滑动窗口的问题:使用一个数组作为双端队列,记录窗口内元素的下标
//1、当新元素进入到窗口,如果当前的值在滑动窗口中最大-->在滑动窗口的尾端移出当前元素之前,当前元素前边的所有元素都不可能是最大值,可以直接去除进行减枝
//2、需要确定滑动窗口已经满足窗口大小,在没有到达窗口大小的时候,不能输出值
//3、需要确定:当遍历数组的时候,滑动窗口的大小是不是已经超过要求的k了,如果超过需要将窗口的尾端向下一位移动
//定义一个数组模拟的双端队列deque,保存窗口中满足要求的下标:
int deq[100010]={0};
int tt=-1;//队尾添加元素,从-1开始
int hh=0;//队头,从0开始,记录窗口的最后位置
vectorres;//记录结果
for(int i=0;i=hh&&i-deq[hh]+1>k)hh++;
//记录当前元素的下标到双端队列中
//判断当前元素与窗口中的元素右端的元素大小,如果是大的就把之前小的从窗口中删除
while(tt>=hh&&nums[i]>=nums[deq[tt]])
{
tt--;
}
//将当前值填入记录窗口下标的双端队列
deq[++tt] = i;
//此时双端队列记录的窗口中,从左到右是从大到小的顺序,只要输出deq[hh]所代表的元素,就是窗口的最大值
//需要判断此时的窗口是不是满足了=k
if(i-k+1>=0)
{
res.push_back(nums[deq[hh]]);
}
}
return res;
}
};
题目链接:LeetCode347、前k个高频元素
1、计算数组元素的频率:通过哈希表(哈希表是“空间换时间 ”,通过哈希函数将数据压缩存储,实现O(1)的查找效率。在解决存在性检测、状态记录等问题有很好的效果)
2、对频率进行排序(堆排序、sort、快排)但是注意是[元素,频率]的键值对
3、对前k个频率进行输出
思路1:使用无序映射unordered_map与小根堆(代码随想录)
(1)小根堆实现通过优先队列priority_queue,但是要维护一个k大小的堆,当大于k的时候,将频率小的弹出,判断的是map中的value-->重载运算符,使其对second进行判断
class Solution {
public:
vector topKFrequent(vector& nums, int k) {
//思路:
// 1、需要求数组中出现数的频率
// 2、比较频率大小,
// 3、返回频率前k个元素
//对于统计出现的频率,可以使用哈希表进行统计,使用unordered_map进行统计
//对于计算频率大小,可以使用堆来获取前k个元素
unordered_map map;
for(auto i : nums)
{
map[i]++;
}
//使用优先队列模拟堆,但是默认是大根堆,需要重载运算符变成小根堆
//注意:小根堆需要判断的是map中的value,而不是key,所以不能直接使用给定的重载,而是需要自己手写一个针对second的重载运算符小根堆
struct greater2{
bool operator()(const pair&a,const pair&b)
{
return a.second>b.second;
}
};
//优先队列定义小根堆
priority_queue ,vector>,greater2> que;
//使用固定大小的小根堆遍历整个数值
for(auto it =map.begin();it!=map.end();it++)
{
que.push(*it);
if(que.size()>k)que.pop();
}
//弹出前k个元素
int i=k;
//记录前k个元素
vectorres;
while(i--)
{
res.push_back(que.top().first);
que.pop();
}
return res;
}
};
难点:
(1)sort对map中的value进行排序(需要先将map转换成vector
难点:
(1)需要先将map转换成vector
(2)需要使用快排对pair的second进行排序