算法学习100天——8 快速排序2
题目地址(912. 排序数组)
https://leetcode-cn.com/problems/sort-an-array/
题目描述
给你一个整数数组 nums,请你将该数组升序排列。
示例 1:
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
示例 2:
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
提示:
1 <= nums.length <= 5 * 104
-5 * 104 <= nums[i] <= 5 * 104
代码
Java Code:
/**
* 快排的过程
* 1. 递归出口
* 2. 找基准点(随机基准点),并将基准点与数组首地址元素交换(或者尾地址的)
* 3. 根据基准点的值,将数组元素分为 小于等于 + 大于 两部分,并记录分界线
* 4. 将尾部基准点交换至分界线处的元素
* 5. 将除开基准值的两两端数组继续执行同样操作
* 最后得到一个升序数组
** 几个要注意的点:
* 1. 基准值可以不随机,但是遇到数组已经是升序或者降序的情况,时间复杂度度可能为O(N²)
* 2. 分界线处的交换要注意基准值的位置,避免二次打乱已排好的顺序
* 3. 递归必须要有出口。。。。
*/
class Solution {
public int[] sortArray(int[] nums) {
fastSort(nums, 0,nums.length - 1);
return nums;
}
private void fastSort(int[] nums, int left, int right){
// 递归出口
if(left >= right){
return;
}
// 随机一个基准点,并交换到数组首位置
generateRandomPosition(nums, left, right);
// 遍历数组,根据基准数排列
int pos = sort(nums, left, right);
// 基准数两边分别递归
fastSort(nums, left, pos - 1);
fastSort(nums, pos + 1, right);
}
private void generateRandomPosition(int[] nums, int left, int right){
int index =left + new Random().nextInt(right - left + 1);
swap(nums, index, right);
}
private int sort(int[] nums, int left, int right){
int i = left;
int pos = i;
// 双指针法,基于基准值对数组元素分类
while(i < right){
if(nums[i] <= nums[right]){
swap(nums, pos, i);
pos++;
}
i++;
}
// 将数组首位与 基准数应该在的位置值交换
swap(nums, pos, right);
// 返回基准数,用于分段
return pos;
}
private void swap(int[] nums, int left, int right){
int temp = nums[left];
nums[left] = nums[right];
nums[right] = temp;
}
}
结果
快排时间复杂度不稳定 ,数组排序还是归并好用一些