作者:小迅
链接:https://leetcode.cn/problems/maximum-frequency-stack/solutions/1998847/by-xun-ge-v-awcf/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
题目
示例
思路
题目需要我们每一次 pop 的时候返回出现频率最大的元素
对于需要记录任意一个数出现多少次使用哈希表无疑是比较方便的,并且查找和维护都是非常方便的,然后插入一个元素就对哈希表进行排序,将出现次数最多的元素排到前面,每次pop的时候就将哈希表头节点弹出,但是这里存在一个问题,当我们存在相同的出现次数时,我们需要选择最近入栈的元素,所有还需要在哈希中记录我们的入栈顺序,当出现次数相同时取最先入栈的元素,但是这样会超时,原因是每插入一个元素就需要排序一次,存在很多次重复排序操作。
优化 使用哈希记录出现次数这个肯定是最优的,那么就需要优化入栈顺序,那么我们直接使用栈来记录顺序,并且始终保存出现次数最多的元素位于栈顶,当需要弹出元素时,只需要弹出栈顶元素即可。那么应该怎么记录呢,我们可以开辟多个栈,每个栈记录相同出现次数的元素的入栈顺序,每次出栈时,只需要取最大出现次数的栈的栈顶即可。
具体实现看代码,注释超级详细
代码
//哈希+辅助栈
struct my_struct {
int id; /* key */
int count;
UT_hash_handle hh; /* makes this structure hashable */
};//哈希结构
typedef struct {
struct my_struct *users;//哈希表头
int *ans[200001];//多个辅助栈
int index;//最大出现次数值
int *top;//每个栈的栈顶值
} FreqStack;
FreqStack* freqStackCreate() {
FreqStack* obj = (FreqStack *)malloc(sizeof(FreqStack));
obj->users = NULL;
obj->top = (int *)malloc(sizeof(int) * 200001);
memset(obj->top, 0, sizeof(int) * 200001);
obj->index = 0;//初始化变量,栈的初始化当有元素时再申请
return obj;
}
void freqStackPush(FreqStack* obj, int val) {
struct my_struct *s = NULL;
HASH_FIND_INT(obj->users, &val, s); /* id already in the hash? */
if (s == NULL) {//当前元素在哈希表中不存在
s = (struct my_struct*)malloc(sizeof(struct my_struct));
s->id = val;//创建哈希节点
s->count = 1;
HASH_ADD_INT(obj->users, id, s); /* id is the key field *///加入哈希表
} else {//存在修改出现次数
++s->count;
}
if (s->count > obj->index) {//每次都记录最大出现次数
obj->index = s->count;
obj->ans[s->count] = malloc(sizeof(int) * 200001);
}
obj->ans[s->count][obj->top[s->count]++] = val;//入栈
return;
}
int freqStackPop(FreqStack* obj) {
int val = obj->ans[obj->index][--obj->top[obj->index]];//出栈,每次出最大出现次数栈的栈顶即可
if (obj->top[obj->index] == 0) {//判断当前栈是否为空
free(obj->ans[obj->index]);//为空释放空间,防止内存泄漏
obj->ans[obj->index] = NULL;
--obj->index;
}
struct my_struct *s = NULL;
HASH_FIND_INT(obj->users, &val, s); /* id already in the hash? */
--s->count;//将对于元素出现次数 -1
return val;
}
void freqStackFree(FreqStack* obj) {
struct my_struct *current_user;//销毁
struct my_struct *tmp;
HASH_ITER(hh, obj->users, current_user, tmp) {
HASH_DEL(obj->users, current_user); /* delete it (users advances to next) */
free(current_user); /* free it */
}
for (int i = 1; i <= obj->index; ++i) {
free(obj->ans[i]);
obj->ans[i] = NULL;
}
free(obj->top);
obj->top;
free(obj);
obj = NULL;
return ;
}
/**
* Your FreqStack struct will be instantiated and called as such:
* FreqStack* obj = freqStackCreate();
* freqStackPush(obj, val);
* int param_2 = freqStackPop(obj);
* freqStackFree(obj);
*/
作者:小迅
链接:https://leetcode.cn/problems/maximum-frequency-stack/solutions/1998847/by-xun-ge-v-awcf/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
class FreqStack {
unordered_map<int, int> cnt;
vector<stack<int>> stacks;
public:
void push(int val) {
if (cnt[val] == stacks.size()) // 这个元素的频率已经是目前最多的,现在又出现了一次
stacks.push_back({}); // 那么必须创建一个新栈
stacks[cnt[val]].push(val);
++cnt[val]; // 更新频率
}
int pop() {
int val = stacks.back().top(); // 弹出最右侧栈的栈顶
stacks.back().pop();
if (stacks.back().empty()) // 栈为空
stacks.pop_back(); // 删除
--cnt[val]; // 更新频率
return val;
}
};
/**
* Your FreqStack object will be instantiated and called as such:
* FreqStack* obj = new FreqStack();
* obj->push(val);
* int param_2 = obj->pop();
*/
作者:小迅
链接:https://leetcode.cn/problems/maximum-frequency-stack/solutions/1998847/by-xun-ge-v-awcf/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
//超时版,只使用哈希,每插入一个元素就需要排序一次,存在很多重复排序操作
typedef struct mylist {
int index;
struct mylist *next;
}mylist;
struct my_struct {
int id; /* key */
int count;
mylist * node;
UT_hash_handle hh; /* makes this structure hashable */
};
typedef struct {
struct my_struct *users;
int index;
} FreqStack;
FreqStack* freqStackCreate() {
FreqStack* obj = (FreqStack *)malloc(sizeof(FreqStack));
obj->users = NULL;
obj->index = 0;
return obj;
}
int com(const struct my_struct *_a, const struct my_struct *_b)
{
return (_a->count == _b->count) ? (_b->node->index - _a->node->index) : (_b->count - _a->count);
}
void freqStackPush(FreqStack* obj, int val) {
struct my_struct *s = NULL;
HASH_FIND_INT(obj->users, &val, s); /* id already in the hash? */
if (s == NULL) {
s = (struct my_struct*)malloc(sizeof(struct my_struct));
s->node = (mylist *)malloc(sizeof(mylist));
s->node->index = obj->index;
s->node->next = NULL;
s->id = val;
s->count = 1;
HASH_ADD_INT(obj->users, id, s); /* id is the key field */
} else {
mylist *node = (mylist *)malloc(sizeof(mylist));
node->index = obj->index;
node->next = s->node;
s->node = node;
++s->count;
}
++obj->index;
return;
}
int freqStackPop(FreqStack* obj) {
HASH_SORT(obj->users, com);
int val = obj->users->id;
--obj->users->count;
obj->users->node = obj->users->node->next;
if (obj->users->count == 0) {
struct my_struct *user = obj->users;
HASH_DEL(obj->users, user); /* user: pointer to deletee */
free(user);
}
return val;
}
void freqStackFree(FreqStack* obj) {
struct my_struct *current_user;
struct my_struct *tmp;
HASH_ITER(hh, obj->users, current_user, tmp) {
HASH_DEL(obj->users, current_user); /* delete it (users advances to next) */
free(current_user); /* free it */
}
free(obj);
obj = NULL;
return ;
}
/**
* Your FreqStack struct will be instantiated and called as such:
* FreqStack* obj = freqStackCreate();
* freqStackPush(obj, val);
* int param_2 = freqStackPop(obj);
* freqStackFree(obj);
*/
作者:小迅
链接:https://leetcode.cn/problems/maximum-frequency-stack/solutions/1998847/by-xun-ge-v-awcf/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。