150. 逆波兰表达式求值
很简单,遇到运算符把栈入口的两个元素弹出来运算即可。
注意向0取整使用int()函数而不是整除,整除是向下取整。
math.ceil是向上取整。
class Solution:
def evalRPN(self, tokens: List[str]) -> int:
stack = []
opr = ('+', '-', '*', '/')
for token in tokens:
if token not in opr:
stack.append(int(token))
else:
tmp = stack.pop()
if token == '+':
stack[-1] += tmp
elif token == '-':
stack[-1] -= tmp
elif token == '*':
stack[-1] *= tmp
else:
stack[-1] = int(stack[-1] / tmp)
return stack[-1]
239. 滑动窗口最大值
这题滑动窗口求最值,维护单调队列即可。CSIT 5500 的streaming章节亦有提到。
单调队列简而言之:“如果一个选手比你小还比你强,你就可以退役了。” (多年前摘自知乎Pecco的文章)
在实现中遇到的困难是,5500课程里给了每一个窗口元素一个时间戳,记录本元素已经入队多久,如果时间戳大于窗口长度,则他必须离队。实际上这种实现在本题中会超时,因此这里花思考改进,streaming的时候因为数据流很大,针对的是相对小的窗口,因此如果窗口过大会超时;这里因为可以访问原数组,因此如果单调队列中存index非entry,在查入队时间时可以直接使用下标相减检查这个元素是否还在窗口。
from collections import deque
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
res = []
monoQue = deque()
for i in range(len(nums)):
while monoQue and nums[i] >= nums[monoQue[-1]]:
monoQue.pop()
monoQue.append(i)
if i - monoQue[0] >= k:
monoQue.popleft()
if i >= k - 1:
res.append(nums[monoQue[0]])
return res
347.前 K 个高频元素
堆就是干这个事情的。
自己写了一版,AC了但是看着不舒服。
import heapq
from collections import Counter
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
priQue = [(value, key) for key, value in Counter(nums).items()]
heapq.heapify(priQue)
while len(priQue) > k:
heapq.heappop(priQue)
return [x[1] for x in priQue]
实际上,看了题解可以不用先全都heapify, 维护一个固定大小的小顶堆即可。
import heapq
from collections import Counter
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
priQue = []
for key,value in Counter(nums).items():
if len(priQue) >= k:
heapq.heappushpop(priQue, (value,key))
else:
heappush(priQue, (value,key))
return [x[1] for x in priQue]
149

被折叠的 条评论
为什么被折叠?



