239. 滑动窗口最大值 - 力扣(LeetCode)
1. 文章链接
2. 看到题目的第一想法
有两个困难,
- 如何保证快速求出滑动窗口内的最大值。
- 如何才能在更新滑动窗口后,立刻知道出去的是不是旧的最大值,进来的是不是新的最大值?
3. 看完代码随想录之后的想法
做成单调递减队列,
也即每次队尾只维护当前窗口内最大的值,右侧则全是降序排列。
如果新元素破了队形,就要更新队列了,但是注意这里不能从队尾pop,而是从队首pop,直到恢复队形。
所以,这个队列中的队尾就是每个窗口的最大值。
4. 实现过程中遇到的困难
太困难了,需要二刷才行。
class Solution:
def maxSlidingWindow(self, nums: List[int], k: int) -> List[int]:
left_idx = 0
right_idx = 0
max_list = []
decrease_dequeue = deque()
for num in nums:
if decrease_dequeue and right_idx - left_idx == k:
if (nums[left_idx] == decrease_dequeue[0]):
decrease_dequeue.popleft()
left_idx += 1
while decrease_dequeue and (decrease_dequeue[-1] < num):
decrease_dequeue.pop()
decrease_dequeue.append(num)
right_idx += 1
if right_idx - left_idx == k:
max_list.append(decrease_dequeue[0])
return max_list
5.学习时长
3小时
347. 前 K 个高频元素 - 力扣(LeetCode)
1. 文章链接
2. 看到题目的第一想法
我不明白怎么把统计的频率求topk后,还能找到他们对应的元素。
3. 看完代码随想录之后的想法
C++中构建一个优先队列,他的比较函数是自定义根据key-value中的value进行比较得到的。 所以他可以实现上面的想法。
4. 实现过程中遇到的困难
import heapq
class Solution:
def topKFrequent(self, nums: List[int], k: int) -> List[int]:
freq_map = dict()
for num in nums:
freq_map[num] = freq_map.get(num, 0) + 1
small_heap = list()
for key, freq in freq_map.items():
heapq.heappush(small_heap, (freq, key))
if len(small_heap) > k:
heapq.heappop(small_heap)
res_list = []
for freq, key in small_heap:
res_list.append(key)
return res_list
注意push和pop的顺序,如果先pop, 那后面的push就会有相应的元素加入,让heap比k长。 如果要先pop,用>=k来限定pop的时机,又逼着heap不得不弹出第k个高频元素,加入一个不确定会不会比pop出的元素频率高的元素,所以是有问题的。
5.学习时长
30分钟。