给你一个整数数组 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 <= 50000
-50000 <= nums[i] <= 50000
速度:
快排:
归并:
堆排序:
解法一:快速排序
思路,如果直接使用原始的快速排序代码,会在某个特别大的case超时,原因是直接选择l作为中枢会使得在某些已排序好的序列中达到最坏情况,使得超时。因此选择中枢时使用随机数选择
class Solution { public: vector<int> sortArray(vector<int>& nums) { srand((unsigned)time(NULL)); //参考leetcode题解使用 quicksort(nums,0,nums.size()-1); return nums; } void quicksort(vector<int>& nums,int l,int r){ if(l<r){ int mid=getPartion(nums,l,r); quicksort(nums,l,mid); quicksort(nums,mid+1,r); } } int getPartion(vector<int>& nums,int l,int r){ int p = rand() % (r - l + 1) + l;//参考leetcode题解使用 swap(nums[l],nums[p]); int tmp=nums[l]; int i=l,j=r; while(i<j){ while(tmp<=nums[j]&&i<j) j--; nums[i]=nums[j]; while(nums[i]<=tmp&&i<j) i++; nums[j]=nums[i]; } nums[i]=tmp; return i; } };
解法二:归并排序
class Solution { public: vector<int> sortArray(vector<int>& nums) { v.resize(nums.size(),0); sort(nums,0,nums.size()-1); return nums; } void sort(vector<int>& nums,int l, int r){ if(l>=r) return; int mid=(l+r)/2; sort(nums,l,mid); sort(nums,mid+1,r); merge(nums,l,mid,r); } void merge(vector<int>& nums,int l,int m,int r){ int i=l,j=m+1,c=l; while(i<=m&&j<=r){ if(nums[i]<=nums[j]) v[c++]=nums[i++]; else v[c++]=nums[j++]; } while(i<=m) v[c++]=nums[i++]; while(j<=r) v[c++]=nums[j++]; for(j=l;j<=r;j++){ nums[j]=v[j]; } } vector<int> v; };
解法三:堆排序
思路:使用大根堆,build之后,每次将0处元素放到末尾,然后fix
class Solution { public: vector<int> sortArray(vector<int>& nums) { sort(nums,nums.size()); return nums; } void sort(vector<int>& nums, int n){ build(nums,n); for(int i=n-1;i>0;i--){ swap(nums[0],nums[i]); fix(nums,i,0); } } void build(vector<int>& nums,int n){ for(int i=n/2-1;i>=0;i--){ fix(nums,n,i); } } void fix(vector<int>& nums,int n,int k){ int tmp=nums[k]; int j=2*k+1; while(j<n){ if(j+1<n&&nums[j+1]>nums[j]) j++; if(tmp>nums[j]) break; nums[k]=nums[j]; k=j; j=2*k+1; } nums[k]=tmp; } };