1. 题目
2. 分析
使用快排进行排序
- 确定左右边界
- 选中基准值
- 指针a指向左边界,从左边界开始找到每一个小于基准值的数字与指针a进行替换,同时指针a右移
- 指针a与基准值替换
- 左边界到指针a前和指针a后到右边界的两个子数组进行排序
3. 代码
3.1 快排
class Solution {
public static int[] sortArray(int[] nums) {
sortArray(nums, 0, nums.length - 1);
return nums;
}
private static void sortArray(int[] nums, int i, int j) {
if (i >= j) {
return;
}
int pre = i;
for (int k = i; k < j; k++) {
if (nums[k] < nums[j]) {
swap(nums, pre++, k);
}
}
swap(nums, pre , j);
sortArray(nums, i, pre - 1);
sortArray(nums, pre + 1, j);
}
public static void swap(int[] t, int a, int b) {
int s = t[a];
t[a] = t[b];
t[b] = s;
}
}
3.2 随机基准值优化
class Solution {
public static int[] sortArray(int[] nums) {
sortArray(nums, 0, nums.length - 1);
return nums;
}
private static void sortArray(int[] nums, int i, int j) {
if (i >= j) {
return;
}
random(nums, i, j);
int pre = i;
for (int k = i; k < j; k++) {
if (nums[k] < nums[j]) {
swap(nums, pre++, k);
}
}
swap(nums, pre , j);
sortArray(nums, i, pre - 1);
sortArray(nums, pre + 1, j);
}
private static void random(int[] nums, int i, int j) {
Random random = new Random();
int t = random.nextInt(j - i) + i;
swap(nums, t, j);
}
public static void swap(int[] t, int a, int b) {
int s = t[a];
t[a] = t[b];
t[b] = s;
}
}
但是在执行一个全是2的case的时候,复杂度是n^2,超时了
3.3 增加桶排
class Solution {
public static int[] sortArray(int[] nums) {
sortArray(nums, 0, nums.length - 1);
return nums;
}
private static void sortArray(int[] nums, int i, int j) {
if (i >= j) {
return;
}
random(nums, i, j);
int pre = i;
//记录一下如果相同元素超过50%,使用其他排序算法
Map<Integer, Integer> map = new HashMap<>();
int max = Integer.MIN_VALUE;
int iMin = Integer.MAX_VALUE ;
int iMax = Integer.MIN_VALUE;
for (int k = i; k < j; k++) {
map.put(nums[k], null == map.get(nums[k]) ? 1 : map.get(nums[k]) + 1);
max = Math.max(max, map.get(nums[k]));
iMin = Math.min(nums[k], iMin);
iMax = Math.max(nums[k], iMax);
if (nums[k] < nums[j]) {
swap(nums, pre++, k);
}
}
if ((double) max / (double)nums.length > 0.5) {
bucketSort(nums, iMax, iMin);
return;
}
swap(nums, pre , j);
sortArray(nums, i, pre - 1);
sortArray(nums, pre + 1, j);
}
private static void bucketSort(int[] nums, int iMax, int iMin) {
int[] a = new int[iMax - iMin + 1];
for (int num : nums) {
a[num - iMin] += 1;
}
int t = 0;
for (int i = 0; i < a.length; i++) {
for (int j = 0; j < a[i]; j++) {
nums[t++] = i + iMin;
}
}
}
private static void random(int[] nums, int i, int j) {
Random random = new Random();
int t = random.nextInt(j - i) + i;
swap(nums, t, j);
}
public static void swap(int[] t, int a, int b) {
int s = t[a];
t[a] = t[b];
t[b] = s;
}
}