题目链接
题目解析
算法原理
使用归并排序来处理
核心: 递归, 拆成俩部分: 先把左边进行排序, 左边排完右边排,然后合并俩个有序数组
很像二叉树的后续遍历
对比快排: 每次都是按照key值来划分俩块,然后递归
代码编写
class Solution {
//合并俩个有序数组
private static int[] merge(int[] arr1, int[] arr2) {
int len1 = arr1.length;
int len2 = arr2.length;
int[] mergeArr = new int[len1 + len2];
//遍历俩个数组,并进行比较
int i = 0, j = 0, count = 0;
while (i < len1 && j < len2) {
//分情况进行插入
if (arr1[i] > arr2[j]) {
mergeArr[count++] = arr2[j++];
} else {
mergeArr[count++] = arr1[i++];
}
}
//此时出来了说明有一个数组遍历完了
//就把另一个数组的元素放进新的数组
while (j < len2) {
mergeArr[count++] = arr2[j++];
}
while (i < len1) {
mergeArr[count++] = arr1[i++];
}
return mergeArr;
}
private static int[] mergeSort(int[] nums, int left, int right) {
//只有一个元素的时候
if (left == right) {
return new int[] { nums[left] };
}
//拆分数组,每次分为俩半
int mid = left + (right - left) / 2;
//继续归并左边
int[] arr1 = mergeSort(nums, left, mid);
//继续归并右边
int[] arr2 = mergeSort(nums, mid + 1, right);
return merge(arr1, arr2);
}
public int[] sortArray(int[] nums) {
return mergeSort(nums, 0, nums.length - 1);
}
}
难点:
1. 合并俩个有序数组
依次比较俩个数组的每一个元素, 谁小谁放进新的数组里面
2. 递归的返回条件
最后数组会分成一个一个的子数组, 然后再进行合并,此时left=right
3. 关于取中点
使用 int mid = left+(right-left)/2,可以基于下标来计算数组的中间值,而nums.length/2 一直算出来的是固定值