在刷力扣215题 数组中的第K个最大的元素时,发现了快速排序随机选取主元的重要性,不然就会被极端的数据把时间复杂度卡到n²。
两种选取主元的时间差异很大
我又试了试调用库函数,发现和我自己写的快速排序时间复杂度差不多
最后使用了快速排序改进的快速选择算法,成功击败了百分之99的人。
代码
class Solution {
public int findKthLargest(int[] nums, int k) {
quickSort(nums,0,nums.length-1,k);
return nums[nums.length-k];
}
public void quickSort(int [] nums ,int left ,int right,int k){
if(left>=right)return;
random_partition(nums ,left ,right);
int zhuyuan = nums[left];
int i = left;
int j = right;
while(i<j) {
while (i < j && nums[j] >= zhuyuan) {
j--;
}
nums[i] = nums[j];
while(i < j && nums[i] <= zhuyuan){
i++;
}
nums[j] = nums[i];
}
nums[i] = zhuyuan;
//如果主元的位置比需要的位置大,就递归左区间
if(i > nums.length-k) quickSort(nums , left , i-1,k);
//如果主元的位置比需要的位置小,就递归右区间
else if(i < nums.length-k)quickSort(nums , i+1 ,right,k);
//如果是等于的话就说明刚好我们只需要这个位置即可,就不需要递归了
}
public void random_partition(int[] nums, int left, int right)
{
int i = left + (int)(Math.random() * (right-left+1));
int t = nums[left];
nums[left] = nums[i];
nums[i] = t;
}
}
如果想学习快速排序,可以参考快速排序这篇文章,个人感觉其实现十分优美。