随机基准 + 三路快排
- 随机选基准:随机抽取区间内数字作为 pivot,从数学概率上杜绝有序数组退化,平均递归深度稳定 O(logn);
- 三路分区 :把区间切分成三段:
[l, left] < key、[left+1, right-1] == key、[right, r] > key,等值元素不再参与后续递归,大量重复数据下效率大幅提升; - 原地交换:仅递归栈开销,无额外数组,空间开销极小,贴合题目「空间尽可能小」要求。

三路指针含义
left:小于 key 区域的右边界 ,初始l-1(空区间);right:大于 key 区域的左边界 ,初始r+1(空区间);i:遍历指针,从头开始扫描未分区元素。
分区循环逻辑
nums[i] < key:交换到左区间,left++,i++(交换过来的数一定小于 key,无需二次校验);nums[i] > key:交换到右区间,right--,i 不变(交换过来的数字还没判断,需要重新校验);nums[i] == key:直接跳过,不做任何交换。

cpp
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
srand(time(NULL));
qsort(nums,0,nums.size()-1);
return nums;
}
void qsort(vector<int>& nums,int l,int r)
{
if(l>=r) return;
int key=getRandom(nums,l,r);
int i=l,left=l-1,right=r+1;
while(i<right)
{
if(nums[i]<key)
swap(nums[++left],nums[i++]);
else if(nums[i]>key)
swap(nums[--right],nums[i]);
else i++;
}
//l left left+1 right right+1 r
qsort(nums,l,left);
qsort(nums,right,r);
}
int getRandom(vector<int>& n,int l,int r)
{
int x = rand();
return n[x % (r-l+1) + l];
}
};