10.第K大的数

第K大的数

题目描述

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

方法一:使用快速排序的思想

1、从大到小排序,每比较完一轮,判断此时走到的数组的索引值i:
2、 i == k - 1,则返回此时索引的数组值
3、 i > k - 1,则第k大的数在此时索引的左边,递归数组左半边
4、i < k - 1,则第k大的数在此时索引的右边,递归数组右半边

方法二:适合海量数据,利用SortedMap

1、利用SortedMap每插入一个数据其结构都是把键按小到大排好序的,
2、map.firstKey为最小的key,map.last为最大的key,
3、先把前面k个数作为key放进map,后面的数逐一和map.firstKey比较,
4、若该数大于map.firstKey,则先remove(map.firstKey),再put(a[i],i)
5、若该数小于或等于map.firstKey,则啥也不做

package 牛客.查找;
/*
 *@Author: helen
 *@Date:   2021/4/21 12:52
 *@Description:
 题目描述
    有一个整数数组,请你根据快速排序的思路,找出数组中第K大的数。
    给定一个整数数组a,同时给定它的大小n和要找的K(K在1到n之间),请返回第K大的数,保证答案存在。
    示例1
        输入      [1,3,5,2,2],5,3
        返回值     2
 */

import java.util.SortedMap;
import java.util.TreeMap;

public class 第K大的数 {
    public int findKth(int[] a, int n, int k) {
        // write code here
        int result = QuickFind(a, 0, n - 1, k);
        return result;
    }
    //方法一:
    public int QuickFind(int[] a, int start, int end, int k){
        int i = start;
        int j = end;
        while(i < j){
            while (i < j && a[i] >= a[j]) j--;
            if(i < j){
                int temp = a[i];
                a[i] = a[j];
                a[j] = temp;
                i++;
            }
            while (i < j && a[i] >= a[j]) i++;
            if(i < j){
                int temp = a[i];
                a[i] = a[j];
                a[j] = temp;
                j--;
            }
        }
        //此时i = j
        if(i < k - 1) {
            return QuickFind(a, i + 1, end, k);
        }
        else if(i > k - 1) {
            return QuickFind(a, start, i - 1, k);
        }
        else {
            return a[i];
        }

    }
    //方法二:
    public int FindK(int[] a, int n, int k){
        SortedMap<Integer, Integer> map = new TreeMap<>();
        for (int i = 0; i < n; i++) {
            if (i < k)
                map.put(a[i], i);
            else{
                if(a[i] > map.firstKey()) {
                    map.remove(map.firstKey());
                    map.put(a[i],i);
                }
            }
        }
        return map.firstKey();
    }

    public static void main(String[] args) {
        第K大的数 obj = new 第K大的数();
        int[] a = {1,3,5,2,2};
        int n = 5;
        int k = 3;
        int kth = obj.findKth(a, n, k);
        System.out.println(kth);
        System.out.println(obj.FindK(a, n, k));
    }
}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值