快速排序是不稳定排序;
随机打乱partition最左边的点
class Solution {
// 随机数种子取当前时间戳
Random rand = new Random(System.currentTimeMillis());
public int[] sortArray(int[] nums) {
sort(nums,0,nums.length-1);
return nums;
}
public void sort(int[] nums,int l,int r){
if(l >= r){return;}
int index = partition(nums,l,r);
sort(nums,l,index-1);
sort(nums,index+1,r);
}
public int partition(int[] nums,int l,int r){
// 最左侧数字与中间随机数字交换
int randIndex = l + rand.nextInt(r-l+1);
swap(nums,l,randIndex);
// 以交换后的最左侧数字为目标值,将数组分为两部分,左侧都小于目标值,右侧都大于目标值
int flag = nums[l];
// 双指针,分别位于除了目标值外的最左与最右
int left = l+1;
int right = r;
while(left <= right){
while(left <= right && nums[left] < flag){left++;}
while(left <= right && nums[right] > flag){right--;};
if(left >= right)break;
// 左右分别找到符合值
swap(nums,left,right);
left++;
right--;
}
swap(nums,l,right);
return right;
}
public void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
leetcode912_23ms_51MB
快速排序2,用for代替while;
class Solution {
Random rand = new Random(System.currentTimeMillis());
public int[] sortArray(int[] nums) {
int len = nums.length;
if(len == 1)return nums;
sort(nums,0,nums.length-1);
return nums;
}
public void sort(int[] nums,int l,int r){
if(l >= r)return;
int index = partion(nums,l,r);
sort(nums,l,index-1);
sort(nums,index+1,r);
}
public int partion(int[] nums,int i,int j){
int ra = i + rand.nextInt(j-i+1);
swap(nums,i,ra);
int temp = nums[i];
int p = i;
for(int ii = i+1;ii <= j;ii++){
if(nums[ii] < temp){
p++;
if(p == ii)continue;
swap(nums,p,ii);
}
}
swap(nums,p,i);
return p;
}
public void swap(int[] nums,int i,int j){
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}
leetcode912_1142ms_54.5MB