找出数组中第 K 大的数

给定一个数组,找出数组中第 K 大的一个数,解析再代码里

package com.hunter.test;

import java.util.Arrays;
import java.util.Scanner;

/**
* 给定一个整形数组,求数组里面第 m 大的数
* 这里假设 m = 3
*/
public class findTheNum {

private final static int m = 3;
public static void main(String args[]){
    Scanner scan = new Scanner(System.in);
    while (scan.hasNext()){
        int n = scan.nextInt();
        int[] arr = new int[n];
        for(int i = 0; i < n; i++){
            arr[i] = scan.nextInt();
        }
        System.out.println("排序:" + getNum1(n,arr));
        System.out.println("非拓展性:" + getNum2(n,arr));
        System.out.println("快速排序:" + getNum3(n,arr,3));
    }
}

/**
 * 最可耻的做法,直接排序然后输出对应的数即可
 * @param n
 * @param arr
 * @return
 */
private static int getNum1(int n, int[] arr) {
    if(arr == null || arr.length < 1)
        return 0;
    Arrays.sort(arr);
    if(n < m)
        return arr[0];
    return arr[m - 1];
}

/**
 * 用一个数组来存储当前查找到的数字,存储最大的四个
 * 但是这样函数可拓展性不高,而且假如现在变成求第 6 大或者第 7 大甚至第 n
 * 函数就变得复杂且没意义了
 * @param n
 * @param arr
 * @return
 */
public static int getNum2(int n,int[] arr){
    if(arr == null || arr.length < 1)
        return 0;
    int[] tp = new int[m];
    for(int i = 0; i < m; i++){
        tp[i] = Integer.MIN_VALUE;
    }
    for(int i = 0; i < n; i++){
        if(arr[i] >= tp[2]){
            tp[0] = tp[1];
            tp[1] = tp[2];
            tp[2] = arr[i];
        }
        else
            if(arr[i] >= tp[1]){
            tp[0] = tp[1];
            tp[1] = arr[i];
            }
            else
                if(arr[i] > tp[0])
                    tp[0] = arr[i];
    }

    return tp[0];
}

public static int getNum3(int n,int[] arr,int k){

    //如果数组的元素个数没有 k 个,输出数组中最大的数
    if(n < k){
        int max = arr[0];

        for(int i = 1; i < n; i++){
            if(arr[i] > max)
                max = arr[i];
        }
        return max;
    }

    //用快速排序的思想进行查找
    return partition(0,n,arr,k);
}

public static int partition(int l,int r ,int[] arr,int k){

    int tp = arr[0];
    int right = r - 1;
    int left = l;
    while(right > left && arr[right] >= tp)
        right--;
    if(left < right)
        arr[left++] = arr[right];

    while (left < right && arr[left] <= tp)
        left++;
    if(right > left)
        arr[right--] = arr[left];

    arr[left] = tp;

    if(left == k)
        return left;
    else
        if(left > k)
            return partition(0,left - 1,arr,k);
    else
        return partition(left+1,right,arr,k);
}

}

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值