第一道题,所有排序都适合在这里练习:912. 排序数组
第二道题,适合快排和堆排:215. 数组中的第K个最大元素
我使用的是双指针版本的快排,双指针版本的快排的核心思想是:每一轮快排选择一个数作为 key,cur 遍历当前划分的区间,使得 key 左边的数小于 key,右边的数大于 key,这样就是升序,反之亦然
快排有很多种写法,我选择的是对于我来说最好理解的那个
温馨提示:LeetCode 那两道题目的数据都加强了,由于快排存在局限性,如果排序的是一个顺序的数组,我们可以用三数取中或者是随机选数来优化性能
但是,如果排序的是一个每一个数都完全相同的数组,那快排就完蛋了,而 LeetCode 那两道题都添加了数组元素全是 1 的样例,所以快排现在无论如何都没法过了
所以这两道题目,用快排的方法过显示的样例就行了
void quicksort(int l, int r, vector<int>& nums) {
if (l >= r) {
return;
}
swap(nums[(l+r)/2], nums[l]);
int key = l, pre = l, cur = l+1;
while(cur <= r) {
if (nums[cur] < nums[key]) {
pre++;
swap(nums[pre], nums[cur]);
}
cur++;
}
swap(nums[pre], nums[key]);
key = pre;
quicksort(l, key-1, nums);
quicksort(key+1, r, nums);
}
func quickSort(l, r int, nums []int) {
if l >= r {
return
}
swap(&nums[(l+r)/2], &nums[l]);
key, pre, cur := l, l, l+1
for cur <= r {
if nums[cur] < nums[key] {
pre++
swap(&nums[pre], &nums[cur])
}
cur++
}
swap(&nums[pre], &nums[key])
key = pre
quickSort(l, key-1, nums)
quickSort(key+1, r, nums)
}
func swap(a, b *int) {
*a, *b = *b, *a
}
Golang 版本比较惨,需要我手动实现 swap
主要有两个目的: