我在Leetcode中遇到了第k个最大数字问题
输入:[3,2,1,5,6,4]且k = 2,输出:5
建议的解决方案:
public int findKthLargest(int[] nums, int k) {
shuffle(nums);
k = nums.length - k;
int lo = 0;
int hi = nums.length - 1;
while (lo < hi) {
final int j = partition(nums, lo, hi);
if(j < k) {
lo = j + 1;
} else if (j > k) {
hi = j - 1;
} else {
break;
}
}
return nums[k];
}
private int partition(int[] a, int lo, int hi) {
int i = lo;
int j = hi + 1;
while(true) {
while(i < hi && less(a[++i], a[lo]));
while(j > lo && less(a[lo], a[--j]));
if(i >= j) {
break;
}
exch(a, i, j);
}
exch(a, lo, j);
return j;
}
private void exch(int[] a, int i, int j) {
final int tmp = a[i];
a[i] = a[j];
a[j] = tmp;
}
private boolean less(int v, int w) {
return v < w;
}
分区不采用O(n),而主函数中的while循环采用O(log n),因此应该为O(nlog n)吗?看起来它使用了Quicksort,但是quicksort的运行时是O(nlogn)。如果quicksort取O(n),这是有道理的,但没有意义。请帮助我了解发生了什么事?
答案 0 :(得分:3)
这是具有平均/预期O(n)运行时间的随机算法。这是因为在随机调整输入列表后,我们通常具有足够好的枢轴,可以期望在每次分区函数调用之后,如果我们找不到目标,但我们会将列表(将在下一个搜索中)大致减少一半。这意味着,即使我们不走运并且不得不连续调用分区函数,我们也会不断将列表大小减小一半,因此,由于O(n)+ O(n / 2)+ O,平均运行时间仍然仅为O(n) (n / 4)+ ... + O(1)仍然是O(n)。