如果是一个有序数组,那么寻找第k的大数则相当简单了,且效率为1。数组排序算法中相对较优的算法为快速排序,效率为N*lgN,将数组从到到小排列,第k大的数则为array[k-1]。
1.快速排序
快排的思想为:从数组中取任意一个值key,将大于key的值放在key右边,小于key的值放在key左边。key的左边和右边则都是有序的了,然后递归key左边的子数组和key右边的子数组,直到每个子数组长度为1,此时,整个数组均有序了。
package adv;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int arr[]= {65,58,95,10,57,62,13,106,78,23,85};
System.out.println("排序前:"+Arrays.toString(arr));
quickSort(arr,0,arr.length-1);
System.out.println("排序后:"+Arrays.toString(arr));
}
public static void quickSort(int[] nums, int left, int right) {
int pivot = 0;
if(left<right) {
pivot = partition(nums, left, right);
quickSort(nums, left, pivot-1);
quickSort(nums, pivot+1, right);
}
}
public static int partition(int[] nums, int left, int right) {
int key = nums[left];
while(left<right) {
while(left<right && nums[right]>=key) {
right--;
}
nums[left] = nums[right];
while(left<right && nums[left]<=key) {
left++;
}
nums[right] = nums[left];
}
nums[left] = key;
return left;
}
}
2.类快排解法
由于只要求找出第k大的数,没必要将数组中所有值都排序。
快排中的partition算法,返回key在数组中的位置,如果key的位置正好等于k-1,那么问题则得到解决,如果key的位置不等于k-1,可使用递归查找对应子数组。直到key的位置等于k-1,则找对问题的解。
package adv;
import java.util.Arrays;
public class Main {
public static void main(String[] args) {
int arr[]= {65,58,95,10,57,62,13,106,78,23,85};
System.out.println("排序前:"+Arrays.toString(arr));
int k = findK(arr,0,arr.length-1,5);
System.out.println("排序后:"+Arrays.toString(arr));
System.out.println("第K大的数字: " + k);
}
public static int findK(int[] nums, int left, int right, int k) {
int i = partition(nums, left, right);
if (i == k - 1) {
return nums[k - 1];
} else if (i > k - 1) {
return findK(nums, left, i - 1, k);
} else if (i < k - 1) {
return findK(nums, i + 1, right, k);
}
return 0;
}
public static int partition(int[] nums, int left, int right) {
int temp = nums[left];
while(left<right) {
//右侧
while(left<right && nums[right]>=temp) {
right--;
}
nums[left] = nums[right];
//左侧
while(left<right && nums[left]<=temp) {
left++;
}
nums[right] = nums[left];
//左侧
}
nums[left] = temp;
return left;
}
}
/*
排序前:[65, 58, 95, 10, 57, 62, 13, 106, 78, 23, 85]
排序后:[10, 13, 23, 57, 58, 62, 65, 106, 78, 95, 85]
第K大的数字: 58
*/
https://blog.youkuaiyun.com/bandaoyu/article/details/84706044