Sliding Window

public class Solution {
	
		public List<Integer> medianSlidingWindow(int[] nums, int k) {
		PriorityQueue<Integer> minHeap = new PriorityQueue<>();
		PriorityQueue<integer> maxHeap = new PriorityQueue<>(Collections.reverseOrder());
		
		List<Integer> result = new ArrayList<>();
		for (int i = 0; i < nums.length; i++) {
			int num = nums[i];
			//new number
			maxHeap.offer(num);
			minHeap.offer(maxHeap.poll());           	//双堆求中位数的套路
				balance(minHeap, maxHeap);
		
				if (i >= k) {
					//remove
					if (nums[i - k] <= maxHeap.peek()) { 	//nums[i-k] 比大根堆的最大值还要小
						maxHeap.remove(nums[i - k]);  	//确认 nums[i-k] 是在maxHeap中
					} else {
						minHeap.remove(nums[i - k]);
					}
				}
				balance(minHeap, maxHeap);
				
				if (i >= k - 1) {   //这里为什么不是 i = k - 1 ?
					result.add(maxHeap.peek());
				}
		}
		
		private void balance(PriorityQueue<Integer> minHeap, PriorityQueue<Integer> maxHeap) {
			//0 <= len(maxHeap) - len(minHeap) <= 1; 1 或者是 0
			//奇偶都在maxHeap.peek(); 偶数的话需要返回左边的值,奇数返回中间的值
			while (maxHeap.size() < minHeap.size()) {
				maxHeap.offer(minHeap.poll());
			}
			while (maxHeap.size() - minHeap.size() > 1) {
				minHeap.offer(maxHeap.poll());
			}
		}
		}
}

最后更新于

这有帮助吗?