1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65
| class LazyHeap: def __init__(self): self.heap = [] self.size = 0 self.remove_cnt = defaultdict(int) def push(self, num): self.apply_remove() heappush(self.heap, num) self.size += 1
def pop(self) -> int: self.size -= 1 return heappop(self.heap)
def pushpop(self, num) -> int: self.apply_remove() return heappushpop(self.heap, num) def top(self) -> int: self.apply_remove() return self.heap[0] def remove(self, num): self.remove_cnt[num] += 1 self.size -= 1
def apply_remove(self): while self.heap and self.remove_cnt[self.heap[0]]: self.remove_cnt[self.heap[0]] -= 1 heappop(self.heap)
class Solution: def medianSlidingWindow(self, nums: List[int], k: int) -> List[float]: left = LazyHeap() right = LazyHeap()
n = len(nums) ans = [0] * (n-k+1) for i, x in enumerate(nums): if left.size <= right.size: left.push(-right.pushpop(x)) else: right.push(-left.pushpop(-x)) if i < k-1: continue if k % 2 == 0: ans[i-k+1] = (-left.top() + right.top()) / 2 else: ans[i-k+1] = -left.top() to_remove = nums[i-k+1] if to_remove > -left.top(): right.remove(to_remove) if left.size > right.size + 1: right.push(-left.pop()) else: left.remove(-to_remove) if left.size < right.size: left.push(-right.pop()) return ans
|