【算法】分治:归并之 912.排序数组(medium)

系列专栏

双指针

模拟算法

分治思想


目录

1、题目链接

2、题目介绍

3、解法

解决方案选择

解题步骤

4、代码


1、题目链接

912. 排序数组 - 力扣(LeetCode)

2、题目介绍

给你一个整数数组 nums,请你将该数组升序排列。

你必须在 不使用任何内置函数 的情况下解决问题,时间复杂度为 O(nlog(n)),并且空间复杂度尽可能小。

示例 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 <= nums.length <= 5 * 104
  • -5 * 104 <= nums[i] <= 5 * 104

3、解法

解决方案选择

为了满足时间复杂度的要求,我们选择使用归并排序(Merge Sort)算法。归并排序是一种分而治之的算法 ,它将数组分成两半,递归地对它们进行排序,然后将结果合并成一个有序数组。这个过程的时间复杂度为 O(nlog(n)),因为它将问题分解成更小的子问题,直到子问题的大小为1(即已经排序),然后将它们合并起来。

解题步骤

  1. 定义辅助函数
    • merge 函数:负责将两个已排序的子数组合并成一个有序数组。它使用了一个临时数组 tmp 来存储合并过程中的元素,以避免在原始数组上进行复杂的元素移动。
    • mergeSort 函数:递归地将数组分成更小的部分,直到每个部分只包含一个元素(自然是有序的),然后调用 merge 函数将它们合并成有序数组。
  2. 归并排序过程
    • 拆分 :通过递归调用 mergeSort,将数组不断拆分成更小的部分,直到每个部分只包含一个元素。
    • 合并 :在递归返回的过程中,使用 merge 函数将相邻的两个已排序的子数组合并成一个有序数组。
  3. 空间复杂度
    • 归并排序的空间复杂度主要由临时数组 tmp 决定,其大小为 nums.size(),因此空间复杂度为 O(n)。
  4. 时间复杂度
    • 归并排序的时间复杂度为 O(nlog(n)),这主要是由于每次递归调用都将问题规模减半,并且合并操作的时间复杂度为 O(n)。

4、代码

cpp 复制代码
class Solution {
public:
    //归并排序
    //
    void merge(vector<int>& nums, vector<int>& tmp, int left, int mid, int right)
    {
        int lsort = left, rsort = mid + 1;//两个需要进行合并区域的第一个元素下标
        int cur = left;//遍历tmp数组的计数器

        while (lsort <= mid && rsort <= right)
        {
            if (nums[lsort] <= nums[rsort])
            {
                tmp[cur++] = nums[lsort++];
            }
            else {
                tmp[cur++] = nums[rsort++];
            }
        }

        //如果有剩余的数,没有参与比较,直接插入到tmp中
        while (lsort <= mid)
        {
            tmp[cur++] = nums[lsort++];
        }
        while (rsort <= right)
            tmp[cur++] = nums[rsort++];

        while (left <= right)
        {
            nums[left] = tmp[left];
            left++;
        }

    }
    //先拆分,再合并
    void mergeSort(vector<int>& nums, vector<int>& tmp, int left, int right)
    {
        if (left < right)
        {
            int mid = (right + left) / 2;
            mergeSort(nums, tmp, left, mid);
            mergeSort(nums, tmp, mid + 1, right);

            merge(nums, tmp, left, mid, right);
        }

    }
    vector<int> sortArray(vector<int>& nums) {
        vector<int> tmp(nums.size());
        mergeSort(nums, tmp, 0, nums.size() - 1);
        return nums;
    }
};

💗感谢阅读!💗

相关推荐
遥感知识服务31 分钟前
Sentinel-1 + DEM + FwDET + 随机森林:从快速水深初估到多因子误差修正
算法·随机森林·sentinel
来一碗刘肉面41 分钟前
顺序表与链表的比较
数据结构·算法·链表
alphaTao1 小时前
LeetCode 每日一题 2026/7/13-2026/7/19
算法·leetcode
nnerddboy1 小时前
脑电信号处理实战 03 | 运动想象脑机接口入门:ERD/ERS、CSP 空间滤波与左右拳想象解码
算法·信号处理
QN1幻化引擎2 小时前
Dalin L — 我造了一门支持中文编程的语言,完整移植到 Rust 了
人工智能·算法·机器学习
Rainy Blue8832 小时前
C转C++速成
c语言·c++·算法
txzrxz2 小时前
二分图详解
数据结构·c++·算法·图论·深度优先搜索·二分图染色
gaosushexiangji3 小时前
数字图像相关DIC系统在结构振动模态测量中的应用
算法
KaMeidebaby3 小时前
卡梅德生物技术快报|如何制备单克隆抗体:小众禽类靶点单抗制备实操流程:双载体抗原交叉筛选完整工艺记录
人工智能·python·深度学习·算法·机器学习
北域码匠4 小时前
Karatsuba乘法超详细解析(原理+流程+性能分析+纯原生C#无第三方库完整实现)
算法·c#·大数乘法·高精度计算·数据结构与算法·分治算法·karatsuba 乘法