由于我们上一道题需要用到归并排序,所以在这里讲解一下归并
归并排序就是将一个数组中数据不断二分,直到分到只有一个为止(左端点是left,右端点是right,那么当left >= right的时候就不需要在分了),此时开始合并,用两个指针分别遍历两个数组,哪个值小就放入新数组中,然后把两个数组的值都遍历完并放入新数组中后,在通过新数组将排序后的值放入原数组中即可。
这里有个非常好理解的思路,就是可以把归并排序当作二叉树的后序遍历,因为要达到当前节点的合并条件,那我们首先需要将其左右子树都排序完,那么最后才会对当前节点进行排序
class Solution {
int[] tmp;
public int[] sortArray(int[] nums) {
tmp = new int[nums.length];
mergeSort(nums,0,nums.length - 1);
return nums;
}
public void mergeSort(int[] nums,int left,int right) {
if(left >= right) return;
//二叉树的后序遍历
int mid = (left + right) / 2;
mergeSort(nums,left,mid);
mergeSort(nums,mid+1,right);
//开始合并
int index = left;
int cur1 = left;
int cur2 = mid+1;
while(cur1 <= mid && cur2<= right) {
tmp[index++] = nums[cur1] <= nums[cur2] ? nums[cur1++] : nums[cur2++];
}
while(cur1 <= mid)
tmp[index++] = nums[cur1++];
while(cur2 <= right)
tmp[index++] = nums[cur2++];
//将数值重新填入
for(int i = left;i <= right;i++){
nums[i] = tmp[i];
}
}
}