LeetCode895.最大频率栈 原题链接:最大频率栈
1. 需要了解的知识点
数据结构
栈结构:后进先出(LIFO) 例:12345进入54321出
unordered_map: 哈希函数组成的 无序 map。(此题unordered_map无序比有序map效率更高)
vector的API
empty() 判断Vector是否为空
back() 返回最末一个元素
push_back() 在Vector最后添加一个元素
pop_back() 移除最后一个元素
2. 思路
确定需要定义的变量类型:
- unordered_map<int,int> maps: 键值key里储存元素(int),值value对应元素频率(int)
- unordered_map<int,vector<int>> res_maps: 键值key里储存元素频率(vector<int>),值value对应该频率下的元素(int)
- int max: 此时栈类最大的频率
3. 难点:
个人观点难点在于:(如果最频繁的元素不只一个,则移除并返回最接近栈顶的元素)。
也就是说:当出现多个为最频繁的数,元素频率都相等,这种情况就要考虑哪个元素是最后入栈,该元素就是我们需要移除并返回的数;
4. 代码注释
class FreqStack {
public:
FreqStack() {
max = 0; /*初始化max*/
}
void push(int x) { /*压栈*/
maps[x]++; /*将各个元素的频率放入map中*/
res_maps[maps[x]].push_back(x); /*vector增加一个元素*/
/*
**** 如果理解不了上面一行替换成下面三行代码也是一样的,就是会增加内存
vector<int> vec= res_maps[maps[x]];
vec.push_back(x);
res_maps[maps[x]] = vec;
*/
if (maps[x] > max) /*在压栈过程中找频率最大的数*/
max = maps[x];
}
int pop() { /*弹出栈顶*/
int res = res_maps[max].back(); /*取出最大频率数(pop的结果)*/
res_maps[max].pop_back(); /*删除最大频率的键值对*/
maps[res]--; /*maps下的频率减一*/
if (res_maps[max].empty()) /*这操作比较难理解*/
max--; /*说明该频率下已经没有元素了,频率减一*/
return res;
}
private:
unordered_map<int,int> maps;
unordered_map<int,vector<int>> res_maps;
int max;
};
/**
* Your FreqStack object will be instantiated and called as such:
* FreqStack* obj = new FreqStack();
* obj->push(x);
* int param_2 = obj->pop();
*/
4. 总结反思
假如原本x的频率为1,增加之后变成2,这里只是在频率为2的vector里新增了一个x,但是并没有删除频率为1的vector中的x。
这样可以保证,当x被弹出(pop)之后,在频率为1的vector里元素的顺序不会被修改。
5. 我写过的智障思路代码
private:
multimap<int,std::pair<int, stack<int>>> maps;
multimap<std::pair<int, int>,std::pair<int,stack<int>>> maps_pop;
int count;
/*看我定义的这类型就知道这写过的代码写的有多智障,频率增加后删除原先的频率就定义成这副鬼样子*/