目录
🚩了解题意
本题的题意很简单,就是将nums数组排成升序即可。
🚩算法原理
本题和颜色分类那个题目很相似,就是从小到大排序。只不过不同的是,这次不是取nums[i]和左右指针相比较了,本题用的是key关键字,而关键字是随机的,不是特定的哪个值。依旧利用的是三种判断思路。
- 如果nums[i]<key,先让left++,然后与nums[i]和nums[left]交换位置,然后i++。
- 如果nums[i]>key,先让--right,然后与nums[i]和nums[right]交换位置。(i不往后,nums[i]依旧是未知数字)
- 如果nums[i]==key i++.
- 最后i和right相遇结束
while(i<right){
if(nums[i]<key)swap(nums[++left],nums[i++]);
else if(nums[i]==key)i++;
else swap(nums[--right],nums[i]);
}
分治快排思想,每次key进行划分,<key和>key进行划分,<key再进行划分,>key也进行划分。
🎈取随机值
在快速排序算法中,为了提高算法的性能和避免出现最坏情况(即当输入数组已经有序时造成快速排序的时间复杂度退化为O(n^2)),经常会使用随机化来选择基准值。选择随机基准值可以降低出现最坏情况的概率,使得快速排序在平均情况下表现更好。
在给定区间 [left, right] 中随机选择基准值时,通过 nums[r%(right-left+1)+left]
的方式可以保证基准值在该区间内是均匀随机选择的,即基准值可以是区间内的任意一个元素,而不是固定选择区间的第一个、最后一个或中间值,从而使得算法更具随机性,降低了最坏情况发生的概率。
nums[r%(right-left+1)+left]
是一个用于在给定范围 [left, right] 内随机选择基准值的方法。让我解释一下这个表达式是如何计算的:
(right - left + 1)
:计算给定范围内元素的数量,即区间长度。r % (right - left + 1)
:生成一个 [0, right - left] 之间的随机数,通过取余操作符%
可以确保生成的随机数在这个范围内。r % (right - left + 1) + left
:将上一步生成的随机数平移至 [left, right] 区间内,即加上 left 的值,从而确保基准值在给定区间内。(因为后面的分治,[right,nums.size()-1]区间中随机值需要+left,否则就不再这个区间了。因此,表达式
nums[r%(right-left+1)+left]
可以通过这种方式在闭区间 [left, right] 内均匀随机选择一个元素作为基准值。
🎈c++中取随机数的步骤
1/设置随机种子:在程序的开头使用 srand(time(NULL)); 设定随机数种子,以确保每次运行程序时生成的随机数不同。
2/生成随机数:
使用 rand() 函数来生成一个伪随机数,比如 int randomNumber = rand();
按照逻辑依次走一遍。
然后我们用分治
从上述的遍历后我们分成了三个部分
- <key [l,left]
- =key [left+1,right-1]
- >key [right,r]
然后我们要进行分治
[l,left]区域继续进行一次快排操作
[right,r]区域继续进行一次快排操作
然后继续调用这个函数<key的区域,然后调用>key的区域,每次分治后的key都是随机取的。
🚩代码实现
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)i++;
else swap(nums[--right],nums[i]);
}
//[l,left] [left+1,right-1] [right,r]
qsort(nums,l,left);
qsort(nums,right,r);
}
int getRandom(vector<int>&nums,int left,int right){
int r=rand();
return nums[r%(right-left+1)+left];
}
};
做好自己。