将数组排序之后,输出第k个最大的元素
快速选择算法
快速选择算法基于快速排序算法,所以我们下来学习一下快速排序
- 确定分界点
x
x
可以是q[l]
q[r]
q[l + r >> 1]
任意一个都是可以的 lr是区间的左右边界 - 调整区间,左边所有的数都
<= x
, 右边所有的数都>= x
x不一定是在中间-
利用两个指针
i
j
, -
指针
i
指向左侧,如果i
指向的数值<x
那么就一直移动,直到i
指向的数>x
就暂时停止;
指针j
指向右侧,如果j
指向的数组>x
,那么就一直移动,直到j
指向的数<x
就暂时停止; -
将这两个指针指向的值交换后,就满足2.2,继续进行步骤2.2操作
-
- 递归处理左右 两个部分
function quick_sort(q, l, r) {
if(l >= r) return;
let i = l - 1, j = r + 1, x = q[l];
while (i < j) {
do i ++; while (q[i] > x);
do j --; while (q[j] < x);
if (i < j) {
[q[i],q[j]] = [q[j],q[i]];
}
}
quick_sort(q, l, j), quick_sort(q, j + 1, r);
}
上面是按照从小到大的顺序排序的
模板建议背过 手撕快速排序
快排时间复杂度:nlong(n)
快速选择算法时间复杂度:O(n)
只用递归一半就好
原因如下:
- 假设在快排第二步的时候,左边区间的个数
< K
个,j结果一定在右边,那么左边就不用再递归了,只用递归右侧部分即可,反之
function quick_sort(q, l, r, k) {
if (l >= r) return q[k];
let x = q[l + r >> 1], i = l - 1, j = r + 1;
while (i < j) {
do i ++; while (q[i] > x); // 从大到小
do j --; while (q[j] < x);
if (i < j) {
[q[i],q[j]] = [q[j],q[i]];
}
}
if (j < k) {
quick_sort(q, j + 1, r, k);
} else {
quick_sort(q, l, j, k);
}
}
var findKthLargest = function(nums, k) {
quick_sort(nums, 0, nums.length - 1, k - 1);
return nums[k - 1];
};
自己来试试:数组中的第K个最大元素