难度:Medium
题目:
给你一个整数数组
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
Related Topics
- 数组
- 分治
- 桶排序
- 计数排序
- 基数排序
- 排序
- 堆(优先队列)
- 归并排序
重点!!!解题思路
第一步:
明确解题思路:使用排序来解决此题,模仿c++中的STL的快速排序思想来解决此题
第二步:
我们使用一个快速排序来对待排序数组进行分区
最后分区以后使用一个插入排序来进行最后的调整
源码+解析:
class Solution {
public int[] sortArray(int[] nums) {
quick_sort(nums,0,nums.length-1); //执行快速排序,传入参数
return nums;
}
public void quick_sort(int[] nums,int l,int r){
__quick_sort(nums,l,r); //接收参数进行快速排序
final_insert_sort(nums,l,r); //最后收尾进行插入排序
}
public void __quick_sort(int[] nums,int l,int r){
while (r-l>16){ //模仿STL的快速排序,当待排序数组长度大于16时进行操作
int i=l,j=r,m=median(nums[l],nums[r],nums[(l+r)/2]); //找到一个中间值,这个值不要求非常准确,只需要保证它不是最大值,也不是最小值即可
do {
while (nums[i]<m) i++;
while (nums[j]>m) j--;
if (i<=j){ //执行到这步相当于num[i]>m,num[j]<m 说明顺序不对,需要换一下
swap(nums,i,j);
i++;
j--;
}
}while (i<=j);
__quick_sort(nums,i,r); //这步很重要,思想为单边递归,右面进行递归,左面进行循环
r=j; //这步其实相当于__quick_sort(nums,l,j) 虽说是相当于 但实际不进行递归操作,进行循环操作加快程序运行速度
}
}
public void final_insert_sort(int[] nums,int l,int r){ //插入算法同理
int ind=l;
for (int i=l+1;i<=r;i++){ //我们先确nums中的最小值,这样我们待排序数组的有序区间就增加了,可以保证排序后的正确性,减少了程序的运行次数,优化插入排序的性能
if (nums[i]<nums[ind]){
ind=i;
}
}
while (ind>l){
swap(nums,ind,ind-1);
ind--;
}
for (int i=l+2;i<=r;i++){ //因为第一个位置已经确定是最小值
int j=i;
while (nums[j]<nums[j-1]){
swap(nums,j,j-1);
j--;
}
}
}
public void swap(int[] nums,int l,int r){
int t=nums[l];
nums[l]=nums[r];
nums[r]=t;
}
public int median(int a,int b,int c){
int max=Math.max(a,Math.max(b,c));
int min=Math.min(a,Math.min(b,c));
if (a!=max && a!=min) return a;
if (b!=max && b!=min) return b;
return c;
}
}
运行结果:
系列持续更新中,喜欢练习算法的那就点个攒吧