每日一题:LeetCode之数组中第K最大元素(包含建堆过程)

在未排序的数组中找到第 k 个最大的元素。请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

示例 1:

输入: [3,2,1,5,6,4] 和 k = 2
输出: 5
示例 2:

输入: [3,2,3,1,2,4,5,5,6] 和 k = 4
输出: 4

思路:对数组进行堆排序,在挑选其中第K大的元素。本文没有使用java封装好的类,手动建堆。
建堆过程:堆的结构其实是一个完全二叉树,大顶堆就是当前节点大于其子节点,小根堆当前节点小于其子节点,我们可以用数组储存。
以大顶堆为例,其中主要包含shiftup()shift down()两个函数shiftup()为上移当前节点直到满足当前节点小于其父节点。shiftdown()为下移当前节点直到为结尾或者当前节点大于其子节点。
1.shiftup()函数在大根堆中是在建堆过程中使用,每遍历到一个新元素,对其进行shiftup()函数。
2.shiftdown()函数用在将整个大顶堆建好后,排序时候使用,将根节点与末尾节点互换,互换后的根节点打破了大顶堆的特性就会执行shiftdown(),直到所有元素排序完。

public int findKthLargest(int[] nums, int k) {
        buildheap(nums);
        int len=nums.length-1;
       
        while(k>1){       
           swap(0,len,nums);  //排序首尾元素互换
           len--;    //下移时不能包含排序好的元素
           shiftdown(nums,0,len);  
           k--;
        }
        return nums[0];
    }
    public void buildheap(int[] nums){   //建堆
        for(int i=1;i<nums.length;i++)
            shiftup(i,nums);
    }
    public void shiftup(int i,int[] nums){  //上移操作
        while(i>0&&nums[i]>nums[(i-1)/2]){
            swap(i,(i-1)/2,nums);
            i=(i-1)/2;
        }
    }
    public void shiftdown(int[] nums,int i,int end){  //下移操作
        int left=(i*2)+1;
        int right=(i*2)+2;
        int temp=0;
        while(right<=end){
            if(nums[left]>nums[right])
                temp=left;
            else
                temp=right;
            
            if(nums[i]>nums[temp])
                break;
            
            swap(i,temp,nums);
            i=temp;
            
            left=(i*2)+1;
            right=(i*2)+2;
        }
        if(left<=end){
            if(nums[i]<nums[left]){
                swap(i,left,nums);
            }
        }
    }
    public void swap(int a,int b,int[] nums){
        int temp=nums[a];
        nums[a]=nums[b];
        nums[b]=temp;
    }
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值