1、快速排序
双指针快排,能搞定含有大量重复元素和序列基本有序的情况。
class Solution {
public int[] sortArray(int[] nums) {
int n = nums.length;
quicksort(nums, 0, n - 1);
return nums;
}
void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
void quicksort(int[] nums, int l, int r) {
if(l >= r) {
return;
}
int index = (int) (Math.random() % (r - l + 1)) + l;
swap(nums, r, index);
int i = l, j = r - 1;
int x = nums[r];
while(i <= j) {
while(i <= j && nums[i] < x) {
i++;
}
while(i <= j && nums[j] > x) {
j--;
}
if(i <= j) {
swap(nums, i, j);
i++;
j--;
}
}
swap(nums, r, i);
quicksort(nums, l, i - 1);
quicksort(nums, i + 1, r);
}
}
技巧就是单趟排序的时候使用首尾双指针,这样即便元素都一样,两个指针相遇位置也是中间,本次排好的pivot位于序列中间,左右两个序列长度平衡,有效避免了极端情况。使用随机数pivot可以解决一般的原序列基本有序的情况。
2、归并排序
class Solution {
int[] temp;
public int[] sortArray(int[] nums) {
int n = nums.length;
temp = new int[n];
mergeSort(nums, 0, n - 1);
return nums;
}
void mergeSort(int[] nums, int l, int r) {
if(l >= r) {
return;
}
int mid = (r - l) / 2 + l;
mergeSort(nums, l, mid);
mergeSort(nums, mid + 1, r);
int i = l, j = mid + 1;
int index = 0;
while(i <= mid && j <= r) {
if(nums[i] <= nums[j]) {
temp[index++] = nums[i++];
} else {
temp[index++] = nums[j++];
}
}
while(i <= mid) {
temp[index++] = nums[i++];
}
while(j <= r) {
temp[index++] = nums[j++];
}
for(int k = 0; k < r - l + 1; k++) {
nums[k+l] = temp[k];
}
}
}
3、堆排序
先构造大根堆,将堆末尾的元素与堆顶进行交换后,重新维护大根堆。循环直至排序完成。
class Solution {
public int[] sortArray(int[] nums) {
heapSort(nums);
return nums;
}
void heapSort(int[] nums) {
buildMaxHeap(nums);
for(int i = 0; i < nums.length; i++) {
swap(nums, 0, nums.length - 1 - i);
maxHeapify(nums, 0, nums.length - 1 - i);
}
}
void buildMaxHeap(int[] nums) {
for(int i = nums.length / 2; i >= 0; i--) {
maxHeapify(nums, i, nums.length);
}
}
void maxHeapify(int[] nums, int i, int n) {
int left = 2 * i + 1;
int right = left + 1;
int mid = i;
if(left < n && nums[left] > nums[mid]) {
mid = left;
}
if(right < n && nums[right] > nums[mid]) {
mid = right;
}
if(mid != i) {
swap(nums, mid, i);
maxHeapify(nums, mid, n);
}
}
void swap(int[] nums, int i, int j) {
int temp = nums[i];
nums[i] = nums[j];
nums[j] = temp;
}
}