【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. Excel-在整个工作簿中查找/替换

    13.在整个工作簿中查找/替换 调范围为:工作簿,默认是工作表:

  2. R连接mysql数据库方法详解

    Warning messages: 1: In odbcDriverConnect("DSN=Rdata;UID=root") : [RODBC] ERROR: state IM0 ...

  3. 汽车C2M模式综述

  4. Kubernetes:应用自动扩容、收缩与稳定更新

    在前面我们已经学习到了 Pod 的扩容.滚动更新等知识,我们可以手动为 Deployment 等设置 Pod 副本的数量,而这里会继续学习 关于 Pod 扩容.收缩 的规则,让 Pod 根据节点服务器 ...

  5. Freeswitch 安装爬坑记录1

    2 Freeswitch的安装 2.1 准备工作 服务器安装CentOS 因为是内部环境,可以关闭一些防火墙设置,保证不会因为网络限制而不能连接 关闭防火墙 查看防火墙 systemctl statu ...

  6. day35前端基础之BOM和DOM

    day35前端基础之BOM和DOM BOM操作 简介 BOM(Browser Object Model)是指浏览器对象模型,它使 JavaScript 有能力与浏览器进行"对话". ...

  7. Flink(八)【Flink的窗口机制】

    目录 Flink的窗口机制 1.窗口概述 2.窗口分类 基于时间的窗口 滚动窗口(Tumbling Windows) 滑动窗口(Sliding Windows) 会话窗口(Session Window ...

  8. android 获取uri的正确文件路径的办法

    private String getRealPath( Uri fileUrl ) { String fileName = null; if( fileUrl != null ) { if( file ...

  9. 编译安装haproxy2.0

    先解决lua环境,(因为centos自带的版本不符合haproxy要求的最低版本(5.3)先安装Lua依赖的包 [root@slave-master lua-5.3.5]# yum install  ...

  10. java输入/输出流的基本知识

    通过流可以读写文件,流是一组有序列的数据序列,以先进先出方式发送信息的通道. 输入/输出流抽象类有两种:InputStream/OutputStream字节输入流和Reader/Writer字符输入流 ...