找出乱序数组第k大的数字(堆排序专场)

打印 上一主题 下一主题

主题 911|帖子 911|积分 2733

使用堆排序来解决《乱序数组第k大的数字》
先放上代码(虽然leetcode要求O(n),但是堆排序是O(nlogn))
`class Solution {
public int findKthLargest(int[] nums, int k) {
int heapSize = nums.length;
buildHeap(nums, heapSize);
for(int i = nums.length - 1; i >= nums.length - k + 1; i--) {
swap(nums, 0, i);
heapSize--;
buildHeap(nums, heapSize);
}
return nums[0];
}
  1. public void buildHeap(int[] nums, int heapSize) {
  2.     for(int i = heapSize / 2 - 1; i >= 0; i--) {
  3.         maximum(nums, i, heapSize);
  4.     }
  5. }
  6. public void maximum(int[] nums, int root, int heapSize) {
  7.     int lChild = root * 2 + 1;
  8.     int rChild = root * 2 + 2;
  9.     int largest = root;
  10.     if (lChild < heapSize && nums[lChild] > nums[largest]) {
  11.         largest = lChild;
  12.     }
  13.     if (rChild < heapSize && nums[rChild] > nums[largest]) {
  14.         largest = rChild;
  15.     }
  16.     // 如果largest不再是入参那个根节点,说明有子节点比它大,要换,换了之后继续往下递归看还有没有
  17.     if (largest != root) {
  18.         swap(nums, root, largest);
  19.         maximum(nums, root, largest);
  20.     }
  21. }
  22. public void swap(int[] nums, int a, int b) {
  23.     int temp = nums[a];
  24.     nums[a] = nums[b];
  25.     nums[b] = temp;
  26. }
复制代码
}`
比较有收获的几个点:

  • 堆里面儿子节点是父亲节点n的n2+1和n2+2
  • 删除堆的堆顶是通过把堆顶元素和堆最后的元素交换,并且heapSize--来实现的
  • 如果有儿子节点比父亲节点大,那么需要交换父亲节点和这个儿子节点,并且继续将交换之后新的儿子节点作为新的根节点往下递归判断
  • 可以从heapSize/2这个节点开始判断,并不断--,最后得到的数组[0]就是正确的堆顶,进行进一步处理即可

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!
回复

使用道具 举报

0 个回复

倒序浏览

快速回复

您需要登录后才可以回帖 登录 or 立即注册

本版积分规则

愛在花開的季節

金牌会员
这个人很懒什么都没写!

标签云

快速回复 返回顶部 返回列表