qidao123.com技术社区-IT企服评测·应用市场

标题: 7.4 分治-归并:LeetCode 912.排序数组 [打印本页]

作者: 海哥    时间: 2025-4-29 17:05
标题: 7.4 分治-归并:LeetCode 912.排序数组

1. 标题链接

LeetCode 912. 排序数组
标题要求:给定一个整数数组 nums,返回该数组按升序排列后的结果。要求时间复杂度为 O(n log n),空间复杂度只管低。

2. 标题描述



3. 示例分析

示例 1
输入:nums = [5,2,3,1]
输出:[1,2,3,5]
分治过程分解
示例 2
输入:nums = [5,1,1,2,0,0]
输出:[0,0,1,1,2,5]
关键点:归并排序是稳固的,相等的元素在合并时保持原有次序。

4. 算法思路

分治思想:分解 → 排序 → 合并

合并操作的关键步调


5. 边界条件与留意事项


6. 代码实现与逐行剖析

  1. class Solution {
  2. public:
  3.     vector<int> tmp; // 全局临时数组,避免递归中反复开辟内存
  4.     vector<int> sortArray(vector<int>& nums) {
  5.         tmp.resize(nums.size());      // 预分配临时数组空间
  6.         mergeSort(nums, 0, nums.size() - 1);
  7.         return nums;
  8.     }
  9.     void mergeSort(vector<int>& nums, int left, int right) {
  10.         if (left >= right) return;    // 终止条件:子数组长度为0或1
  11.         int mid = (left + right) / 2; // 计算中间点(建议改为防溢出写法)
  12.         mergeSort(nums, left, mid);   // 递归排序左半部分
  13.         mergeSort(nums, mid + 1, right); // 递归排序右半部分
  14.         // 合并两个有序子数组
  15.         int cur1 = left, cur2 = mid + 1, i = 0;
  16.         while (cur1 <= mid && cur2 <= right) {
  17.             // 稳定排序:保留相等元素的原始顺序
  18.             tmp[i++] = (nums[cur1] <= nums[cur2]) ? nums[cur1++] : nums[cur2++];
  19.         }
  20.         // 处理左子数组剩余元素
  21.         while (cur1 <= mid) tmp[i++] = nums[cur1++];
  22.         // 处理右子数组剩余元素
  23.         while (cur2 <= right) tmp[i++] = nums[cur2++];
  24.         
  25.         // 将临时数组复制回原数组
  26.         for (int j = left; j <= right; j++) {
  27.             nums[j] = tmp[j - left]; // 计算偏移量
  28.         }
  29.     }
  30. };
复制代码

代码剖析


总结

归并排序通过分治策略实现了稳固的 O(n log n) 排序,尤其适合处理大规模数据。其焦点在于递归分解与合并操作,合并时需留意稳固性和临时数组的空间管理。本文代码通过预分配全局临时数组优化了空间效率,但在极端情况下需考虑中间点计算的溢出题目。理解归并排序的实现细节,有助于把握分治思想在其他算法中的应用(如逆序对统计、外部排序等)。

免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。




欢迎光临 qidao123.com技术社区-IT企服评测·应用市场 (https://dis.qidao123.com/) Powered by Discuz! X3.4