Partition
Partition
April 15, 2024
- Partition Template
- Quick Sort
- Top K Split(Quick Selection): (n = k/1/n-k-1)
- Top Kth Smallest
- Top Kth Largest
Partition Template
int partition(vector<int>& nums, int start, int end) {
int pivot = nums[start]; // 初始化一个待比较数据;
int i = start, j = end;
while (i < j) {
// 从后往前查找,直到找到一个比pivot更小的数
while (i < j && nums[j] >= pivot) --j;
nums[i] = nums[j]; // 将更小的数放入左边
// 从前往后找,直到找到一个比pivot更大的数
while (i < j && nums[i] <= pivot) ++i;
nums[j] = nums[i]; // 将更大的数放入右边
}
// 循环结束,i与j相等
nums[i] = pivot;
return i; // 返回待比较数据最终位置
}Quick Sort
void QuickSort(vector<int>& nums, int start, int end) {
if (start >= end) return;
int idx = partition(nums, start, end);
QuickSort(nums, start, idx - 1);
QuickSort(nums, idx + 1, end);
}Top K Split
- 将快速排序改成快速选择,即我们希望寻找到一个位置,这个位置左边是
k个比这个位置上的数更小的数,右边是n - k - 1个比该位置上的数大的数,我将它命名为TopKSplit,找到这个位置后停止迭代,完成了一次划分。
// Quick Selection
void TopKSplit(vector<int>& nums, int k, int left, int right) {
// 寻找到第k个数停止递归,使得nums数组中index左边是前k个小的数,index右边是后面n-k个大的数
int idx = partition(nums, left, right);
if (idx == k) return;
else if (idx < k) TopKSplit(nums, k, idx + 1, right);
else TopKSplit(nums, k, left, idx - 1);
}Usages
Top K Smalls
vector<int> TopKSmalls(vector<int>& nums, int k) {
TopKSplit(nums, k, 0, nums.size() - 1);
return vector<int>(nums.begin(), nums.begin() + k);
}Kth small
int TopKthSmall(vector<int>& nums, int k) {
TopKSplit(nums, k - 1, 0, nums.size() - 1);
return nums[k - 1];
}Top K Larges
vector<int> TopKLarges(vector<int>& nums, int k) {
// parttion是按从小到大划分的,如果让index左边为前n-k个小的数,则index右边为前k个大的数
TopKSplit(nums, nums.size() - k, 0, nums.size() - 1); // change k to nums.size() - k
return vector<int>(nums.begin() + nums.size() - k, nums.end());
}Kth large
int TopKthLarge(vector<int>& nums, int k) {
// parttion是按从小到大划分的,如果让index左边为前n-k个小的数,则index右边为前k个大的数
TopKSplit(nums, nums.size() - k, 0, nums.size() - 1); // change k to nums.size() - k
return nums[nums.size() - k];
}Only Sort Top K Smalls
// 只排序前 k 个小的数
// 获得前 k 小的数 O(n),进行快排 O(klogk)
vector<int> TopKSortLeft(vector<int>& nums, int k) {
TopKSplit(nums, k, 0, nums.size() - 1);
vector<int> topk = vector<int>(nums.begin(), nums.begin() + k);
QuickSort(topk, 0, topk.size() - 1);
topk.insert(topk.end(), nums.begin() + k, nums.end());
return topk;
}Only Sort Top K Larges
// 只排序后 k 个大的数
// 获得前 k 小的数 O(n),进行快排 O(klogk)
vector<int> TopKSortLeft(vector<int>& nums, int k) {
TopKSplit(nums, nums.size() - k, 0, nums.size() - 1);
vector<int> topk = vector<int>(nums.begin() + nums.size() - k, nums.end());
QuickSort(topk, 0, topk.size() - 1);
topk.insert(topk.begin(), nums.begin() + nums.size() - k, nums.end());
return topk;
}