【LeetCode】895. Maximum Frequency Stack 解题报告(Python)

作者: 负雪明烛
id: fuxuemingzhu
个人博客: http://fuxuemingzhu.cn/


题目地址:https://leetcode.com/problems/maximum-frequency-stack/description/

题目描述:

Implement FreqStack, a class which simulates the operation of a stack-like data structure.

FreqStack has two functions:

push(int x), which pushes an integer x onto the stack.
pop(), which removes and returns the most frequent element in the stack.
If there is a tie for most frequent element, the element closest to the top of the stack is removed and returned.

Example 1:

Input:
["FreqStack","push","push","push","push","push","push","pop","pop","pop","pop"],
[[],[5],[7],[5],[7],[4],[5],[],[],[],[]]
Output: [null,null,null,null,null,null,null,5,7,5,4]
Explanation:
After making six .push operations, the stack is [5,7,5,7,4,5] from bottom to top. Then: pop() -> returns 5, as 5 is the most frequent.
The stack becomes [5,7,5,7,4]. pop() -> returns 7, as 5 and 7 is the most frequent, but 7 is closest to the top.
The stack becomes [5,7,5,4]. pop() -> returns 5.
The stack becomes [5,7,4]. pop() -> returns 4.
The stack becomes [5,7].

Note:

  1. Calls to FreqStack.push(int x) will be such that 0 <= x <= 10^9.
  2. It is guaranteed that FreqStack.pop() won’t be called if the stack has zero elements.
  3. The total number of FreqStack.push calls will not exceed 10000 in a single test case.
  4. The total number of FreqStack.pop calls will not exceed 10000 in a single test case.
  5. The total number of FreqStack.push and FreqStack.pop calls will not exceed 150000 across all test cases.

题目大意

构造一个能弹出最大频率值的栈,如果有多个值出现的都是最大频率且相等,那么返回最靠近栈顶的那一个。

解题方法

同时优化两个目标:出现的频率和出现的索引。所以天然想到用优先级队列。python的优先级队列是个最小堆,而我们要优化的目标是求最大,因此,使用负号即可。

使用m保存出现的次数,使用index保存索引,使用q表示堆。

把出现的次数和出现的索引取反进堆,这样每次弹出堆的时候都是把这两个目标优化了的。pop的时候要更新频率。

我考虑了以下问题:

我觉得是否有个问题?因为pop的过程中并没有更正已经进堆的那些数字的频率,也就是堆里面仍然是以前的频率。这里是否有问题?

其实,事实上这么想是错的,我们堆里面保留的并不是每个数字真实的频率,而是它入堆的时候的频率。当每次Pop的时候会把各个字符出现的频率恢复到它入堆前的样子(题目给出了如果同样的频率时,弹出最后push进去的数字)。当这个数字是最大频率数字,并且多次出现的时候,尽可能弹出靠最后的进入数字保证了提前进入堆的那些数字的频率是正确的。

这是个巧妙的解法,而且第一眼看上去好像是错的。非常有意思。

堆的平均时间复杂度是O(1),空间复杂度是O(N)。

代码如下:

class FreqStack(object):

    def __init__(self):
self.m = collections.defaultdict(int)
self.q = []
self.index = 0 def push(self, x):
"""
:type x: int
:rtype: void
"""
self.m[x] += 1
heapq.heappush(self.q, (-self.m[x], -self.index, x))
self.index += 1 def pop(self):
"""
:rtype: int
"""
val = heapq.heappop(self.q)[2]
self.m[val] -= 1
return val # Your FreqStack object will be instantiated and called as such:
# obj = FreqStack()
# obj.push(x)
# param_2 = obj.pop()

参考资料:

https://leetcode.com/problems/maximum-frequency-stack/discuss/163416/Java-Priority-Queue-easy-understand

日期

2018 年 9 月 18 日 —— 铭记这一天

【LeetCode】895. Maximum Frequency Stack 解题报告(Python)的更多相关文章

  1. [LeetCode] 895. Maximum Frequency Stack 最大频率栈

    Implement FreqStack, a class which simulates the operation of a stack-like data structure. FreqStack ...

  2. LeetCode 895. Maximum Frequency Stack

    题目链接:https://leetcode.com/problems/maximum-frequency-stack/ 题意:实现一种数据结构FreqStack,FreqStack需要实现两个功能: ...

  3. 【LeetCode】654. Maximum Binary Tree 解题报告 (Python&C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 递归 日期 题目地址:https://leetcode ...

  4. 【LeetCode】716. Max Stack 解题报告(C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 双栈 日期 题目地址:https://leetcode ...

  5. 【LeetCode】62. Unique Paths 解题报告(Python & C++)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 题目地址:https://leetcode.com/problems/unique-pa ...

  6. 【LeetCode】456. 132 Pattern 解题报告(Python)

    [LeetCode]456. 132 Pattern 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fu ...

  7. 【LeetCode】853. Car Fleet 解题报告(Python)

    [LeetCode]853. Car Fleet 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxu ...

  8. 【LeetCode】71. Simplify Path 解题报告(Python)

    [LeetCode]71. Simplify Path 解题报告(Python) 标签(空格分隔): LeetCode 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://f ...

  9. 【LeetCode】376. Wiggle Subsequence 解题报告(Python)

    [LeetCode]376. Wiggle Subsequence 解题报告(Python) 作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.c ...

随机推荐

  1. getdelim函数

    利用getdelim函数分割读取字段,将文件制表符替换为空格符 1 #include <stdio.h> 2 #include <stdlib.h> 3 4 int main( ...

  2. zabbix监控php状态

    环境介绍: php /usr/loca/php nignx /usr/loca/nginx  配置文件都是放在extra中 修改php-fpm的配置文件启动状态页面 pm.status_path = ...

  3. Python基础之格式化输出的三种方式

    目录 1. 格式化输出的三种方式 1.1 占位符 1.2 format格式化 1.3 f-string格式化 1. 格式化输出的三种方式 在程序中,需要将输出信息打印成固定的格式,这时候就需要格式化输 ...

  4. linux下vim的安装与配置(centos)

    1.vim的安装 #yum search vim   //查看vim相关软件信息 #yum install -y vim*  //在线安装vim 2.vim的配置 (1)~/.viminfo 在vim ...

  5. JAVA中数组的基本概念与用法

    JAVA中数组的基本概念与用法 1. 数组的定义与特点 数组的一种引用数据类型 数组中可以同时存放多个数据,但是数据的类型必须统一 数组的长度在开始时就需要确定,在程序运行期间是不可改变的 虽然可以使 ...

  6. Spark(十二)【SparkSql中数据读取和保存】

    一. 读取和保存说明 SparkSQL提供了通用的保存数据和数据加载的方式,还提供了专用的方式 读取:通用和专用 保存 保存有四种模式: 默认: error : 输出目录存在就报错 append: 向 ...

  7. Oracle——创建存储过程

    有个超级详细的关于存储过程的帖子:https://www.cnblogs.com/snowballed/p/6766867.html Oracle-存储过程(procedure.function.pa ...

  8. sqlserver 删除表分区

    我们都知道,SQL server2008R2企业版以及一些其它的版本支持分区函数,当你在这些数据库备份后想在一些不支持分区函数的数据库做还原时,就会失败. 下面我们来解决这个问题. 1.备份数据库!备 ...

  9. RocketMQ应用及原理剖析

    主流消息队列选型对比分析 基础项对比 可用性.可靠性对比 功能性对比 对比分析 Kafka:系统间的流数据通道 RocketMQ:高性能的可靠消息传输 RabbitMQ:可靠消息传输 RocketMQ ...

  10. angular过滤器在html和js中的使用

    在HTML中使用格式为:{{数据 | 过滤器名称:条件一:条件二--}}:过滤条件间使用:隔开 例如: 在代码中一般格式为:  变量 = $filter("过滤器名称")(被过滤数 ...