寻找第k大的数

给定一个整数数组arr,同时给定它的大小n和要找的K(K在1到n之间),返回第K大的数。
解法一: 结合快排思想,将数组从大到小排序的过程中返回确定好的元素的下标,与k比较,将范围逐渐缩小。

public class Test {
    public static void main(String[] args) {
        int[] arr = new int[]{6,4,5,7,8};

        int n = findKth(arr, 5, 2);
        
        System.out.println(n);
    }

    public static int findKth(int[] a, int n, int K) {
        // write code here
        int left = 0;
        int right = n - 1;

        int k = K-1; // 若数组“有序”,第k大为K-1下标的数

        while (true) {
            int index = partition (a, left, right); // 将返回下标数与k值比较
            if (k == index) {                       // 相等说明找到了
                return a[index];                    // 返回index数值
            } else if (index < k) {         // index < k说明要找的数字还在右边
                left = index + 1;           // 则将left置位index + 1,直接找右半部分
            } else {
                right = index - 1;          // 反之找左半边
            }
        }
    }
        
    public static int partition (int[] arr, int left, int right) {
        // 取第一个(left下标)数为key
        // 将剩余数与key比较
        int key = arr[left];
        int l = left; // l代表下标比较小的位置

        for (int i = left; i <= right; i++) {  // 用i遍历数组
            if (arr[i] > key) {                // 找出比key大的数
                l++;                           // l及l之前的数都比key大,所以l++
                swap(arr, l, i);               // 把arr[l]与arr[i]交换位置
            }
        }

        // 循环结束后l前边的数字比key大,l后边的数字比key小

        swap(arr, left, l);     // 最终将key的值放到l位置上
        return l;               // 返回key的下标l

        // 结束之后key值左边比key大,key值右边比key小
    }

    private static void swap(int[] arr, int a, int b) {
        int temp = arr[a];
        arr[a] = arr[b];
        arr[b] = temp;
    }
}

以上也可以将partition 函数换成快速排序的partition函数

	public static int partition (int[] arr, int left, int right) {
        int l = left;
        int r = right;
        int key = arr[left];

        while(l < r) {
            while(l < r && arr[r] <= key) {
                r--;
            }
            if (l < r) {
                arr[l] = arr[r];
                l++;
            }
            while(l < r && arr[l] >= key) {
                l++;
            }
            if (l < r) {
                arr[r] = arr[l];
                r--;
            }
        }        
        return l;
    }
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值