寻找第K大

有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。

给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。

示例1

输入

[1,3,5,2,2],5,3

输出

2

//这题应该是用快排的思想:例如找49个元素里面第24大的元素,那么按如下步骤:
//1.进行一次快排(将大的元素放在前半段,小的元素放在后半段),假设得到的中轴为p
//2.判断 p == k ,如果成立,直接输出a[p],(因为前半段有k - 1个大于a[p]的元素,故a[p]为第K大
//的元素)
//3.如果 p  > k, 则第k大的元素在前半段
//4.如果p  <  k, 则第k大的元素在后半段

public class Solution {
    public static int findKth(int[] a, int n, int K) {
        return findKth(a,0,n-1,K);
    }
    private static int findKth(int[] arr, int left, int right, int k) {
        int index = partition(arr,left,right);  //此时index对应的值为第index+1大的值
        if(k < index+1){
            return findKth(arr,left,index-1,k); // 在左子数组中继续找
        }else if (k > index+1) {
            return findKth(arr,index+1,right,k);  // 在右子数组继续找
        }else {
            return arr[index];
        }
    }
    private static int partition(int[] arr, int left, int right) {
        /*
        从左往右找比基准值小的数,从右往左找比基准值大的数,交换
         */
        // 选取最右边的值为基准值
        // 从大到小快排
        int baseValue = arr[right];
        while (left<right) {
            while (left<right && arr[left]>baseValue) {
                left++;
            }
            while (left<right && arr[right]<baseValue) {
                right--;
            }
            if (left < right) {
                int tmp = arr[left];
                arr[left] = arr[right];
                arr[right] = tmp;
            }
        }
        int tmp = arr[left];
        arr[left] = baseValue;
        baseValue = tmp;
        return left;
    }

    public static void main(String[] args) {
        int[] arr = {9,5,2,7,3,6,4};
        int n = 7;
        int k =3;
        int pos = findKth(arr,n,k);
        System.out.println(pos);
        }
}

 

posted @ 2021-04-26 14:10  待到花开  阅读(136)  评论(0)    收藏  举报