快速选择算法及C++代码
一. 快速选择算法分析
快速选择算法是指:利用快速排序算法的思想,计算得到【给定位置(可能是第一个位置,可能是中间位置)】的数在排序后的位置的【下标】的算法。
应用场景:找出给定数组的第k大的数。如Leetcode第215题。
二. C++代码
2.1 源代码
以数组首位为例,代码如下(示例):
int quick_selection(vector<int>& nums) {
int l = 0, r = nums.size() - 1;
int i = l+1, j = r; // nums[l]为pivot
while (true) {
while (i < r && nums[i] <= nums[l]) i++; // i < r 是为了限制i最大到r; 找到nums[l]之后比nums[l]大的第一个数
while (j > l && nums[j] >= nums[l]) j--; // j > l 是为了限制j最小到l;找到nums[r]之前比nums[l]小的第一个数
if (i >= j) break;
swap(nums[i], nums[j]); // 快速排序思想,将nums[l]大小的数各放在一侧
}
swap(nums[l], nums[j]); // 快速排序思想,将nums[j]放到左右侧的中间
return j;
}
2.2 变体
1.可以在函数头规定需要的范围,如:
int quick_selection(vector<int>& nums, int l, int r)
1.pivot可以选择数组中间,如:
int pivot = (l + r) / 2;
int pivot = (l + r) >> 1; //两种不同的方法取中间值
三. 应用
以Leetcode第215题为例,其代码如下:
// 来自《LeetCode 101:和你一起你轻松刷题(C++)》
int findKthLargest(vector<int>& nums, int k) {
int l = 0, r = nums.size() - 1, target = r - k + 1;
while (l < r) {
int mid = quick_selection(nums, l, r);
if (mid == target) return nums[mid];
else if (mid < target) l = mid + 1;
else r = mid - 1;
}
return nums[l];
}
int quick_selection(vector<int>& nums, int l, int r) {
int i = l + 1, j = r;
while (true) {
while (i < r && nums[i] <= nums[l]) i++;
while (j > l && nums[j] >= nums[l]) j--;
if (i >= j) break;
swap(nums[i], nums[j]);
}
swap(nums[l], nums[j]);
return j;
}