LeetCode215 KthLargestElementInAnArray

LeetCode215 KthLargestElementInAnArray

题目描述

在未排序的数组中找到第 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

解答

解法一:利用快速排序

假设数组长度为n。利用快速排序思想,但不用将所有数组元素全部排好序。只需要找到当前关键字所在的索引为n-k就可以(此时,该位左边的值都比关键字小,右边的都比关键字大),但是对于单独的左右两边来说可以是无序的。swap(函数为自定义交换函数)。

public static void fastSort(int[] a, int left, int right, int k){
    if (left>=right)
        return;
    int key = a[left];
    int iLeft = left;
    int iRight = right;
    while (iLeft<iRight){
        while (a[iRight]>=key && iLeft<iRight){
            iRight--;
        }
        while (a[iLeft]<=key && iLeft<iRight){
            iLeft++;
        }
        swap(a, iRight,iLeft);
    }
    swap(a,iLeft,left);

    if (iLeft<k){
        fastSort(a, iLeft+1, right, k);  //往右边找
    }else if(iLeft>k){
        fastSort(a, left,iLeft-1,k);
    }

}
解法二:利用堆排序

假设数组长度为n。利用堆排序,首先构建一个顶点个数为K的小顶堆,注意是小顶堆。构建完以后,将堆顶元素nums[0]与nums[i]进行比较,若是nums[i]比较大,则与0位置处交换,再重新调整堆,i+1。重复这一步,直到i遍历完整个数组。

//解法二:利用堆排序,构建结点个数为k小顶堆,不断进行调整,最后的小顶堆顶点就是答案
public static int solve2(int[] nums, int k){
    //构建小顶堆
    for (int i=k/2-1;i>=0;i--){
        adjustHeap(nums,i,k);
    }
    //将小顶堆堆顶元素与索引为i的元素进行比较,若是nums[i]较大,则交换位置,将其放置堆顶,再调整推。
    for (int i=k;i<nums.length;i++){
        if (nums[0]<nums[i]){
            swap(nums,0,i);
            adjustHeap(nums,0, k);
        }
    }
    return nums[0];
}

//对索引为i处的结点往下调整。index:循环不变量,表示的是当前需要调整的结点的索引
public static void adjustHeap(int[] a, int index, int length){
    //取出当前元素
    int temp = a[index];
    //遍历左右子树中结点值更小的那个
    for (int k= 2*index+1; k<length; k=2*k+1){
        if (k+1<length && a[k]>a[k+1])
            k=k+1;
        //与当前结点作比较,孩子结点更小,则交换,否则调整结束·
        if (a[k]<temp){
            a[index]=a[k];
            index=k;
        }else
            break;
    }
    a[index]=temp;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值