依旧使用快排中的 Partion解决问题(分治)
需要注意的是,本题如果不对Partion进行随机优化,那么有些样例通过时间复杂度较高,所以在Partion中加入了随机优化。
class Solution{
public int findKthLargest(int[] nums, int k) {
if (k == 0 || nums.length == 0)
return -1;
return quickSearch(nums, 0, nums.length - 1, k);
}
private int quickSearch(int[] nums, int l, int r, int k) {
// 每快排切分1次,找到排序后下标为j的元素,如果j+1恰好等于k,nums[j]即为所求
int j = randPartition(nums, l, r);
if (j + 1 == k){
return nums[j];
}
if (j + 1 < k){
return quickSearch(nums, j + 1, r, k);
}
if (j + 1 > k){
return quickSearch(nums, l, j - 1, k);
}
return -1;
}
// 快排切分,返回下标j,使得比nums[j]大的数都在j的左边,比nums[j]小的数都在j的右边
private static int randPartition(int[] nums, int l, int r) {
int index = (int)(Math.random()*(r-l+1))+l;
swap( nums, l, index);
int v = nums[l];
int j = l;
for (int i = l + 1; i <= r; i++) {
if (nums[i] > v){
swap(nums, j+1, i);
j ++;
}
}
swap(nums, l, j);
return j;
}
// 自定义swap函数
private static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void main(String[] args) {
int[] temp = {4, 1, 5, 3, 2};
int res = new Solution().findKthLargest(temp, 3);
System.out.println(res);
}
}
但是最初选取 left 和 right 两个边界中的随机数时,是采用下面的代码中的两种方式,结果是无法AC的,在idea中有时候也会报错,尚未发现这种随机数生成的问题在哪!!!
import java.util.Random;
class Solution{
private static Random random = new Random();
public int findKthLargest(int[] nums, int k) {
if (k == 0 || nums.length == 0)
return -1;
return quickSearch(nums, 0, nums.length - 1, k);
}
private int quickSearch(int[] nums, int l, int r, int k) {
// 每快排切分1次,找到排序后下标为j的元素,如果j+1恰好等于k,nums[j]即为所求
int j = partition(nums, l, r);
if (j + 1 == k){
return nums[j];
}
if (j + 1 < k){
return quickSearch(nums, j + 1, r, k);
}
if (j + 1 > k){
return quickSearch(nums, l, j - 1, k);
}
return -1;
}
// 快排切分,返回下标j,使得比nums[j]大的数都在j的左边,比nums[j]小的数都在j的右边
private static int partition(int[] nums, int l, int r) {
//int index = l + random.nextInt(r - l) + 1;
int index = l + random.nextInt(r) % (r-l+1) + l;//生成随机索引
swap( nums, l, index);
int v = nums[l];
int j = l;
for (int i = l + 1; i <= r; i++) {
if (nums[i] > v){
swap(nums, j+1, i);
j ++;
}
}
swap(nums, l, j);
return j;
}
// 自定义swap函数
private static void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
public static void main(String[] args) {
int[] temp = {4, 1, 5, 3, 2};
int res = new Solution().findKthLargest(temp, 3);
System.out.println(res);
}
}