hot100 堆专题
1 数组中的第K个最大元素1.1 法一 使用优先队列java中PriorityQueue默认是小根堆遍历数组offer进去当堆的size大于k了就poll()最后返回peek()堆顶元素就是第K大的那个class Solution { public int findKthLargest(int[] nums, int k) { PriorityQueueInteger minHeap new PriorityQueue(); for (int num : nums) { minHeap.offer(num); if (minHeap.size() k) { minHeap.poll(); } } return minHeap.peek(); } }1.2 法二 手动构造大根堆构建大顶堆利用堆的特性完全二叉树结构从数组最后一个非叶子节点向前遍历通过 maxHeapify 方法调整每个子树为大顶堆最终让整个数组满足「堆顶元素是当前堆中最大值」的大顶堆特性。逐步移除堆顶最大值循环 k-1 次执行以下操作将堆顶当前最大值与堆的最后一个元素交换把最大值 “移出” 堆的有效范围缩小堆的有效大小并重新调整堆为大顶堆保证新的堆顶仍是剩余元素的最大值。获取结果经过 k-1 次移除最大值的操作后此时堆顶元素就是数组中第 K 大的元素直接返回即可。class Solution { public int findKthLargest(int[] nums, int k) { int heapSize nums.length; buildMaxHeap(nums, heapSize); for (int i nums.length - 1; i nums.length - k 1; i--) { swap(nums, 0, i); heapSize--; maxHeapify(nums, 0, heapSize); } return nums[0]; } public void buildMaxHeap(int[] nums, int heapSize) { for (int i heapSize / 2 - 1; i 0; i--) { maxHeapify(nums, i, heapSize); } } public void maxHeapify(int[] nums, int i, int heapSize) { int l 2 * i 1, r 2 * i 2, largest i; if (l heapSize nums[l] nums[largest]) { largest l; } if (r heapSize nums[r] nums[largest]) { largest r; } if (largest ! i) { swap(nums, i, largest); maxHeapify(nums, largest, heapSize); } } public void swap(int[] nums, int i, int j) { int temp nums[i]; nums[i] nums[j]; nums[j] temp; } }2 前K个高频元素不难但是很容易写错要多写几遍getOrDefault()不是getOrDeafault()用优先队列定义大根堆要会写遍历HashMap要会写数据类型是Map.EntryInteger,IntegerMap和Entry都是大写的entrySet() entry.getKey() entry.getValue()。class Solution { public int[] topKFrequent(int[] nums, int k) { HashMapInteger, Integer map new HashMap(); for (int num : nums) { map.put(num, map.getOrDefault(num, 0) 1); } PriorityQueueint[] que new PriorityQueue((p1,p2) - { return p2[1] - p1[1]; }); for (Map.EntryInteger, Integer entry : map.entrySet()) { que.offer(new int[] {entry.getKey(), entry.getValue()}); } int[] res new int[k]; for (int i 0; i k; i) { res[i] que.poll()[0]; } return res; } }3 数据流的中位数难左堆大顶堆装 “较小的一半”堆顶是这一半里最大的数比如 [1,2] 的堆顶是 2右堆小顶堆装 “较大的一半”堆顶是这一半里最小的数比如 [3,4] 的堆顶是 3最终要保证左堆大小 ≤ 右堆大小 1且左堆所有数 ≤ 右堆所有数。class MedianFinder { private PriorityQueueInteger maxHeap; private PriorityQueueInteger minHeap; public MedianFinder() { maxHeap new PriorityQueue((a, b) - b - a); minHeap new PriorityQueue(); } public void addNum(int num) { maxHeap.offer(num); if (!minHeap.isEmpty() maxHeap.peek() minHeap.peek()) { minHeap.offer(maxHeap.poll()); } if (maxHeap.size() - minHeap.size() 1) { minHeap.offer(maxHeap.poll()); } else if (minHeap.size() maxHeap.size()) { maxHeap.offer(minHeap.poll()); } } public double findMedian() { if (maxHeap.size() minHeap.size()) { return (maxHeap.peek() minHeap.peek()) / 2.0; } else { return maxHeap.peek() * 1.0; } } }
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/2434164.html
如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!