python–leetcode–堆
239.滑动窗口最大值
滑动窗口最大值:给定数组,给定窗口大小,随窗口滑动取得当前窗口最大值
思路:保持当前窗口的最大值,使用大顶堆(小顶堆元素取反),如果最大值索引不在滑动窗口内,则弹出。(这题也可以使用单调队列或者别的做法)
from typing import List
from heapq import heappop, heappush
def maxSlidingWindow(nums: List[int], k: int) -> List[int]:
lens = len(nums)
if lens < k:
return []
res = []
heap = []
for i in range(k):
heappush(heap, (-nums[i], i))
res.append(-heap[0][0])
for i in range(k, lens):
heappush(heap, (-nums[i], i))
while heap[0][1] < i - k + 1:
heappop(heap)
res.append(-heap[0][0])
return res
# print(maxSlidingWindow(nums = [1,3,-1,-3,5,3,6,7], k = 3))
253. 会议室 II
会议室 II:给定起始和结束时间,需要会议之间不会有时间冲突,计算至少需要多少间会议室,才能满足这些会议安排
思路:先按照起始时间进行排序,维持一个结束时间的小顶堆,下一次会议的开始时间和堆顶元素比较,若大于等于则弹出该堆顶元素,会议结束时间入堆,统计最后堆的长度
def minMeetingRooms(intervals: List[List[int]]) -> int:
if not intervals:
return 0
intervals.sort()
free = [intervals[0][1]]
for i in range(1, len(intervals)):
if intervals[i][0] >= free[0]:
heapq.heappop(free)
heapq.heappush(free, intervals[i][1])
return len(free)
# print(minMeetingRooms(intervals = [[0,30],[5,10],[15,20]]))
358. K 距离间隔重排字符串
K 距离间隔重排字符串:相同的字母在新的字符串中间隔至少k 个单位距离
思路:使用Counter计数,根据当前数目和索引构建大顶堆,每次弹出数目最多的元素,使用一个队列保持k间隔后,该元素还有余量的情况下进堆,最终判定得到的得到的重排字符串是否用完所有元素(即长度是否与原始字符串相等)
from heapq import heapify, heappush, heappop
from collections import Counter, deque
def rearrangeString(s: str, k: int) -> str:
if k == 0:
return s
s_count = Counter(s)
queue = deque()
res = ''
max_heap = [(-v, k) for k, v in s_count.items()]
heapify(max_heap)
while max_heap:
num, c = heappop(max_heap)
res += c
queue.append((num + 1, c)) # num为负数,反向减一
if len(queue) == k:
cur_n, cur_c = queue.popleft()
if cur_n < 0: # cur_n为负数,说明还没用完
heappush(max_heap, (cur_n, cur_c))
return res if len(res) == len(s) else ''
# print(rearrangeString('abb', 2))