给你一个整数数组 nums
,请你将该数组升序排列。
示例 1:
1 2
| 输入:nums = [5,2,3,1] 输出:[1,2,3,5]
|
示例 2:
1 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
快速排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public int[] sortArray(int[] nums) { quickSort(nums, 0, nums.length-1); return nums; }
public int Partition(int[] nums , int left , int right){ int pivot = nums[left]; while(left < right){ while(left < right && nums[right] >= pivot) right--; nums[left] = nums[right]; while(left < right && nums[left] <= pivot) left++; nums[right] = nums[left]; } nums[left] = pivot; return left; }
public void quickSort(int[] nums, int left, int right){ if(left < right){ int pivot = Partition(nums, left, right); quickSort(nums, left, pivot-1); quickSort(nums, pivot+1, right); } } }
|
时间复杂度:确定中枢的时间复杂度为O(n),基于随机选取主元的快速排序时间复杂度为期望 O(nlogn),最坏的情况即数组有序的情况下时间复杂度为O(n^2)
空间复杂度:O(h),其中h 为快速排序递归调用的层数。最坏情况下,即数组有序的情况下,需 O(n)的空间,最优情况下每次都平衡,此时整个递归树高度为logn,空间复杂度为 O(logn)
堆排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44
| class Solution { public int[] sortArray(int[] nums) { heapSort(nums, nums.length); return nums; }
public void adjustHeap(int[] nums, int k, int len){ while(2 * k + 1 <= len-1){ int i = 2 * k + 1; if(i < len-1 && nums[i] < nums[i+1]){ i++; } if(nums[k] < nums[i]){ swap(nums, k, i); k = i; }else{ break; } } } public void buildHeap(int[] nums, int len){ for(int i = len/2-1 ; i >= 0; i--){ adjustHeap(nums, i, len); } }
public void heapSort(int[] nums, int len){ buildHeap(nums, len); for(int i = 0 ; i < nums.length; i++){ System.out.println(nums[i]); } for(int i = len-1; i > 0; i--){ swap(nums, 0, i); adjustHeap(nums, 0, i); } } public void swap(int[] nums, int i, int j){ int temp = nums[i]; nums[i] = nums[j]; nums[j] = temp; } }
|
时间复杂度:$O(nlogn)$。初始化建堆的时间复杂度为 $O(n)$,建完堆以后需要进行 n−1次调整,一次调整的时间复杂度为 $O(logn)$,那么n−1次调整即需要 $O(nlogn)$的时间复杂度。因此,总时间复杂度为 $O(n+nlogn)=O(nlogn)$
空间复杂度:O(1),只需要常数的空间存放若干变量。
归并排序
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32
| class Solution { public int[] sortArray(int[] nums) { mergeSort(nums, 0, nums.length - 1); return nums; }
public void mergeSort(int[] nums, int left, int right) { if (left < right) { int mid = (left + right) / 2; mergeSort(nums, left, mid); mergeSort(nums, mid + 1, right);
int[] temp = new int[right - left + 1]; int i = left; int j = mid + 1; int k = 0; while (i <= mid && j <= right) { if (nums[i] <= nums[j]) { temp[k++] = nums[i++]; } else { temp[k++] = nums[j++]; } } while (i <= mid) temp[k++] = nums[i++]; while (j <= right) temp[k++] = nums[j++]; System.arraycopy(temp, 0, nums, left, right-left+1); } }
}
|
时间复杂度:O(nlogn)。归并排序每次都将当前待排序的序列折半成两个子序列递归调用,然后再合并两个有序的子序列,而每次合并两个有序的子序列需要 O(n),所以我们可以列出归并排序运行时间 T(n)的递归表达式:T(n)=2T(2/n)+O(n)
空间复杂度:O(n)。我们需要额外 O(n)空间的 tmp数组
冒泡排序(超时)
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28
| class Solution { public int[] sortArray(int[] nums) { bubbleSort(nums, nums.length); return nums; }
public void bubbleSort(int[] nums, int len){ boolean flag = false; int i = 0; while(i < len){ for(int j = len-1; j > i ; j--){ if(nums[j] < nums[j-1]){ swap(nums, j, j-1); flag = true; } } if(!flag) break; i++; } }
private void swap(int[] nums, int index1, int index2) { int temp = nums[index1]; nums[index1] = nums[index2]; nums[index2] = temp; }
}
|
时间复杂度:$O(n^2)$
空间复杂度:$O(1)$