牛客网刷题-寻找第K大

65 篇文章 0 订阅

问题描述

有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。

输入描述:
输入一个数组、数组长度、k大

输出描述:
输出k大坐标

示例

示例1

输入
[1,3,5,2,2],5,3

输出
2

解决思路

分析

本题与之前的最小的K个数思路相类似,有兴趣的小伙伴可以看看之前的文章,这里只通过变形的快速排序实现。

方法

  1. 通过快速排序的思路实现,当快速排序后的基准值与K相等时,则找到了第K大值(快速排序此处用的降序排序)。

代码实现

public class Solution {
    public int findKth(int[] a, int n, int K) {
        // write code here
        return find(a, 0, n - 1, K);
    }

    public int find(int[] a, int start, int end, int K) {
        // 找基准
        int povitIndex = partition(a, start, end);
        // 判断基准跟k的关系
        if (povitIndex + 1 < K) {
            return find(a, povitIndex + 1, end, K);
        }
        if (povitIndex + 1 > K) {
            return find(a, start, povitIndex - 1, K);
        }
        // 当基准等于K时,返回
        return a[povitIndex];
    }

    // 降序排列
    private int partition(int[] a, int start, int end) {
        int i = start;
        int j = end + 1;
        int povit = a[start];
        while (true) {
            // 从左往右找第一个小于基准值的
            while (a[++i] > povit) {
                // 如果i超过end范围,跳出,说明没有大于基准值的
                if (i >= end) break;
            }
            // 从右向左找第一个大于基准值的
            while (a[--j] < povit) {
                // 如果j超过start,跳出,说明没有小于基准值的
                if (j <= start) break;
            }
            // 如果i大于j,跳出,不需要交换
            if (i >= j) break;
            // 小于基准值的元素和大于基准值的元素交换,大于基准值的元素往后,小于基准值的元素往前
            exchange(a, i, j);
        }

        // 交换0和大于基准值的元素,因为是降序排列
        exchange(a, start, j);
        return j;
    }

    // 交换值
    private void exchange(int[] a, int i, int j) {
        int temp = a[i];
        a[i] = a[j];
        a[j] = temp;
    }
}

小伙伴如果想测试的话,可以直接到牛客网这个链接做测试

寻找第K大-牛客网

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值