给定一个数组,找出数组中第 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);
}
}