NC88 寻找第K大

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

给定一个整数数组 a ,同时给定它的大小n和要找的 k ,请返回第 k 大的数(包括重复的元素,不用去重),保证答案存在。
要求:时间复杂度 O(nlogn),空间复杂度O(1)
数据范围:0≤n≤1000, 1≤K≤n,数组中每个元素满足0≤val≤10000000

示例1
输入:[1,3,5,2,2],5,3
返回值:2

示例2
输入:[10,10,9,9,8,7,5,6,4,3,4,2],12,3
返回值:9
说明:
去重后的第3大是8,但本题要求包含重复的元素,不用去重,所以输出9   

第K大,因此下标为n-k

import java.util.*;

public class Solution {
    public int findKth(int[] a, int n, int K) {
        // write code here
        Arrays.sort(a);
        return a[n-K];
    }
}

快排方式:双指针方式遍历,一旦比基数小则换,而基准归位时,由于是升序,则基准大于最后一个位置时,才调换【如果不剪枝直接调换会造成大于基准的值放到最左边,导致排序出错】,递归时加上该基准值递归,一轮调换后也许当前下标的后面并不一定都是小于该值的比如:arr->56184,一轮后54186,此时l=r=3(值为8),这个时候基准不能换,那么后续则不能递归下一轮。

import java.util.Arrays;

public class HeapDemo {
    public static void main(String[] args) {
        int arr[] = new int[]{9,8,7,6,5,4,3,2,1};
        int left = 0,right = arr.length-1;
        quickSort(arr,left,right);
        Arrays.stream(arr).forEach(System.out::print);

    }

    private static void quickSort(int[] arr, int left, int right) {
        int l = left,r = right;
        if(left>=right) return;
        int base = arr[left];
        while (l<r){
            while (arr[l]<=base && l<r) l++;
            while (arr[r]>=base && l<r) r--;
            if(l<r){
                int swap = arr[l];
                arr[l] = arr[r];
                arr[r] = swap;
            }
        }
        // 基准归位
        if(arr[left]>arr[l]) {
            arr[left] = arr[l];
            arr[l] = base;
        }
        quickSort(arr,left,r-1);
        quickSort(arr,r,right);
    }
}

或者

l = left+1;r = right
while(true){
	while (l<=right && arr[l]<=base ) l++;
	while (r>=left+1 && arr[r]>=base) r--;
	if(l>r) break;
	swap(arr,l,r);
	l++;r--;
}
swap(arr,left,r);// r会到基准的位置
quickSort(arr,left,r-1);
quickSort(arr,r+1,right);

这里l<=r,也可以,让r到基准位置

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值