分治专题(二):归并排序的核心思想与进阶应用
前言
归并排序是经典的分治法应用,其核心在于'分而治之'的思想。通过不断划分,将一个复杂问题逐步拆解成若干规模更小的子问题,以递归方式求解,再将解合并,从而解决初始问题。本文将围绕归并排序的基本原理,结合排序数组的题目,深入剖析归并排序在分治中的实际应用。
第二章:归并排序的应用与延展
2.1 归并排序(medium)
题目链接:912. 排序数组
题目描述:
给定一个整数数组 nums,请将该数组按升序排列。
示例 1:
- 输入:
nums = [5,2,3,1] - 输出:
[1,2,3,5]
示例 2:
- 输入:
nums = [5,1,1,2,0,0] - 输出:
[0,0,1,1,2,5]
解法(归并排序)
算法思路:
归并排序的过程充分体现了'分而治之'的思想,基本步骤分为以下两部分:
- 分:将数组一分为二,递归地继续分割,直到每个子数组的长度为 1,确保所有分块都已排序。
- 治:将两个已排序的子数组合并成一个有序数组,最终返回整个数组的有序结果。
具体步骤:
- 使用中间点将数组分成
[left, mid]和[mid + 1, right]两部分。 - 递归对左右区间进行排序。
- 在排序好的左右子数组中,使用双指针将较小的元素依次合并到临时数组
tmp中。 - 合并完成后,将
tmp数组的内容拷贝回原数组。
C++ 代码实现
class Solution {
vector<int> tmp; // 临时数组用于存储合并结果
public:
vector<int> sortArray(vector<int>& nums) {
tmp.resize(nums.size());
mergeSort(nums, 0, nums.size() - 1);
return nums;
}
// 归并排序
{
(left >= right) ;
mid = (left + right) / ;
(nums, left, mid);
(nums, mid + , right);
cur1 = left, cur2 = mid + , i = ;
(cur1 <= mid && cur2 <= right) {
tmp[i++] = nums[cur1] <= nums[cur2] ? nums[cur1++] : nums[cur2++];
}
(cur1 <= mid) tmp[i++] = nums[cur1++];
(cur2 <= right) tmp[i++] = nums[cur2++];
( j = ; j < i; ++j) {
nums[left + j] = tmp[j];
}
}
};


