力扣 912. 排序数组

news2024/11/25 4:51:24

文章目录

  • 一、题目描述
  • 二、题解
    • 1.快速排序
    • 2.堆排序
    • 3.二路归并排序


一、题目描述

给你一个整数数组 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.快速排序

快速排序,时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),空间复杂度 O ( log ⁡ n ) O(\log n) O(logn)

class Solution {
public:
    vector<int> sortArray(vector<int> &nums) {
        quickSort(nums, 0, nums.size() - 1);
        return nums;
    }

private:
    void quickSort(vector<int> &nums, int begin, int end) {
        if (begin < end) {
            int pivot = partition(nums, begin, end);
            quickSort(nums, begin, pivot - 1);
            quickSort(nums, pivot + 1, end);
        }
    }

    int partition(vector<int> &nums, int begin, int end) {
        int pivot_num = nums.at(begin);

        while (begin < end) {
            while (begin < end && nums.at(end) >= pivot_num) {
                end--;
            }
            nums.at(begin) = nums.at(end);
            while (begin < end && nums.at(begin) <= pivot_num) {
                begin++;
            }
            nums.at(end) = nums.at(begin);
        }

        nums.at(begin) = pivot_num;
        return begin;
    }
};

2.堆排序

堆排序,时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),空间复杂度 O ( 1 ) O(1) O(1)

class Solution {
public:
    vector<int> sortArray(vector<int> &nums) {
        buildMaxHeap(nums);
        for (int i = static_cast<int>(nums.size() - 1); i >= 0; i--) {
            swap(nums.at(0), nums.at(i));
            heapAdjust(nums, 0, i);
        }
        return nums;
    }

private:
    /**
     * 构建大根堆
     */
    void buildMaxHeap(vector<int> &nums) {
        for (int i = static_cast<int>(nums.size()) / 2 - 1; i >= 0; i--) {
            heapAdjust(nums, i, static_cast<int>(nums.size()));
        }
    }

    /**
     * 调整以root为根的二叉树
     * @param nums 存储二叉树元素的数组
     * @param root 根节点
     * @param len 包括根节点在内要调整的元素总数
     */
    void heapAdjust(vector<int> &nums, int root, int len) {
        int tmp = nums.at(root);  // 本轮需要被筛选的值

        /* 从root的孩子开始逐层向下调整 */
        for (int child = 2 * root + 1; child < len; child = 2 * child + 1) {
            /* 选取两个孩子中值较大的那个节点与父节点进行比较 */
            if ((child + 1) < len && nums.at(child + 1) > nums.at(child)) {
                child++;
            }

            /* 如果两个孩子都不大于当前根节点,则结束当前层的调整
             * 如果某一个孩子大于当前根节点,则将该孩子换到当前根上 */
            if (nums.at(child) <= tmp) {
                break;
            } else {
                nums.at(root) = nums.at(child);
                root = child;  // 提前准备下一层循环
            }
        }

        /* 将筛选的值放到最终位置上 */
        nums.at(root) = tmp;
    }
};

3.二路归并排序

二路归并排序,时间复杂度 O ( n log ⁡ n ) O(n\log n) O(nlogn),空间复杂度 O ( n ) O(n) O(n)

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        mergeSort(nums, 0, static_cast<int>(nums.size() - 1));
        return nums;
    }

private:
    void mergeSort(vector<int> &nums, int begin, int end) {
        if (begin < end) {
            int mid = begin + (end - begin) / 2;
            mergeSort(nums, begin, mid);
            mergeSort(nums, mid + 1, end);
            merge(nums, begin, mid, end);
        }
    }

    /**
     * 将两个子数组合并为一个大数组
     * @param nums 数据
     * @param begin 第一个子数组的起始元素下标
     * @param mid 第一个子数组的结束元素下标,它后面一个元素即为第二个子数组的起始元素
     * @param end 第二个子数组的结束元素下标
     */
    void merge(vector<int> &nums, int begin, int mid, int end) {
        vector<int> supply(nums.size());  // 辅助数组
        int i, before, after;

        /* 将数据从nums中拷贝到records中 */
        for (i = begin; i <= end; i++) {
            supply.at(i) = nums.at(i);
        }

        /* 依次将两个子数组的最小值复制到大数组中 */
        for (before = begin, after = mid + 1, i = begin; before <= mid && after <= end; i++) {
            if (supply.at(before) < supply.at(after)) {
                nums.at(i) = supply.at(before++);
            } else {
                nums.at(i) = supply.at(after++);
            }
        }

        /* 处理剩余数据 */
        while (before <= mid) {
            nums.at(i++) = supply.at(before++);
        }
        while (after <= end) {
            nums.at(i++) = supply.at(after++);
        }
    }
};

在这里插入图片描述

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.coloradmin.cn/o/627914.html

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈,一经查实,立即删除!

相关文章

精细消费 年轻人和父母的奇妙交汇

日本社会学家三浦展结合对日本“311”大地震后的社会观察&#xff0c;提出了“第四消费时代”&#xff0c;即人们在经历了消费社会充分的发展过程之后&#xff0c;社会上逐渐兴起了低欲望、乐于共享、重视环保的消费理念。 在当时&#xff0c;主流观点普遍认为中国还处于大众化…

JWT单点登录

单点登录 文章目录 单点登录零、用户模块内容以及设计一、问题的提出二、单点登录SSO1.1 什么是单点登录1.2 单点登录的技术实现机制 二、远程调用方式RPC三、JWT的使用3.1 session的使用原理3.2 JWT介绍3.3 JWT原理3.4 JWT的使用 四、CAS实现单点登录的原理四、CAS的安装和代码…

十二、进程间通信

目录 目录 零、前置知识 一、什么是进程间通信 &#xff08;一&#xff09;含义 &#xff08;二&#xff09;发展 &#xff08;三&#xff09;类型 1.管道 2.System V IPC 3.POSIX IPC 二、为什么要有进程间通信 三、怎么进行进程间通信 &#xff08;一&#xff09;…

Snipaste工具推荐

Snipaste Snipaste 不只是截图&#xff0c;善用贴图功能将帮助你提升工作效率&#xff01; 新用户&#xff1f; 截图默认为 F1&#xff0c;贴图为 F3&#xff0c;然后请对照着 快捷键列表 按一遍&#xff0c;体会它们的用法&#xff0c;就入门啦&#xff01; 遇到了麻烦&…

Java通过Ip2region实现IP定位

我们在一些短视频平台上可以看到,视频作者或评论区可以显示IP地址,这其实就是根据IP获取到的我们可以通过一些在线网站就可以看到我们当前的公网IP和IP定位,最近有个需求也需要通过请求获取客户端的IP和IP的定位,于是通过一系列的百度,最终选择使用Ip2region这个工具库来进行定…

flutter的自定义系列雷达图

自定义是flutter进阶中不可缺少的ui层知识点&#xff0c;这里我们来总结下&#xff1a; 在Flutter中&#xff0c;自定义绘制通常是通过使用CustomPaint和CustomPainter来实现的。 创建CustomPaint组件 首先&#xff0c;需要创建一个CustomPaint组件。CustomPaint是一个Widge…

MobPush 厂商通道申请指南

华为厂商申请 创建应用 登录华为开发者联盟&#xff0c;注册您的应用&#xff0c;在应用信息中获取APP ID和Client Secret 配置SHA256证书指纹 在华为开发者联盟配置SHA256证书指纹。获取及配置请参见华为官方文档配置AppGallery Connect 设置消息回执 集成华为厂商通道SDK…

带你了解二进制

目录 视频参考&#xff1a; 讲解&#xff1a;​编辑 运算&#xff1a; 1001&#xff08;二进制&#xff09; 9&#xff08;十位数&#xff09;1111&#xff08;二进制&#xff09; 15&#xff08;十位数&#xff09;11001&#xff08;二进制&#xff09; 25&#xff08;…

第二章 搭建TS环境

搭建 TypeScript 的开发环境。一个舒适、便捷且顺手的开发环境&#xff0c;不仅能大大提高学习效率&#xff0c;也会对我们日常的开发工作有很大帮助。 这一节我们就来介绍 VS Code 下的 TypeScript 环境搭建&#xff1a;插件以及配置项。对于 TS 文件的执行&#xff0c;我们会…

设计模式(十):结构型之外观模式

设计模式系列文章 设计模式(一)&#xff1a;创建型之单例模式 设计模式(二、三)&#xff1a;创建型之工厂方法和抽象工厂模式 设计模式(四)&#xff1a;创建型之原型模式 设计模式(五)&#xff1a;创建型之建造者模式 设计模式(六)&#xff1a;结构型之代理模式 设计模式…

备战2月面试8家大厂,成功上岸字节(Java岗)定级T2-2,分享一下我的面试心得

最近在公众号上看到一位道友的字节面经&#xff0c;可以说是深有感触了&#xff01; 他的背景是杭州某中厂的Java后端开发&#xff0c;本科毕业5年&#xff0c;最近2个月面试了PDD、小红书、字节等多个大厂。几乎都拿到了Offer&#xff0c;最终选择了字节2-2。以下是他的一些分…

Navicat对postgresql导入导出的坑

Navicat导出postgresql中的表&#xff0c;再新建数据库导入时通常会报错&#xff0c;往往是因为自增id导致的 可以看到&#xff0c;再次导入时会报错&#xff01; 解决办法如下&#xff1a; 解决办法&#xff1a; 重新导入&#xff0c;并执行以下命令&#xff1a;&#xff08…

Python从入门到精通_第0讲_Python的学习路线整理

写在最前&#xff1a; 为什么开这个专栏&#xff1a; 之前我做过一个专栏&#xff0c;专门介绍Python爬虫技术&#xff0c;这一专栏收获了很多朋友们的点赞收藏和关注。但是在爬虫技术专栏中&#xff0c;对于Python语言本身的讲解并不是很细致&#xff0c;由于Python在爬虫、数…

Unity 安装 wwise

先下载 https://www.audiokinetic.com/zh/download 安装的时候要选sdk 就是20g的那个 然后运行 选择unity 可以看到这个界面 好&#xff0c;现在开始要安装离线包 直接项目里点 第二个 装好后 他会提示你 无法找到unity安装的地址 1 打开你的 unity 编辑器 2 在unity安装的…

CorelDRAW矢量绘图2023中文版下载

市面上的矢量绘图工具虽然很多&#xff0c;但权威又专业的却不多&#xff0c;选到不好用的工具&#xff0c;会极大的影响自己创作&#xff0c;CorelDRAW简称cdr&#xff0c;是一款功能强大的矢量图制作软件&#xff0c;一说到矢量图制作&#xff0c;大家都会不由自主地想到cdr。…

车牌识别之UI(Tkinter + OpenCV显示Picture和Video)

画一张总图&#xff1a; 图形界面开发 本篇只介绍图形界面开发。 遇到的第一个问题就是选择什么开发语言和技术。因为我之前用Python做过Tkinter的小东西&#xff0c;所以这次还是用Python Tkinter OpenCV来搞吧。 这里面需要注意几个地方&#xff1a; 1. Tkinter 的布局 …

ADManager Plus:提升企业人员管理效率的全能工具

导言&#xff1a; 在现代企业中&#xff0c;高效的人员管理是取得成功的关键。随着企业规模的扩大和人员数量的增加&#xff0c;传统的人工管理方法已经无法满足快速变化的需求。ADManager Plus作为一款全能的人员管理工具&#xff0c;通过自动化和集成的方式&#xff0c;为企…

一文即可了解!自动化回归测试工具

目录 前言&#xff1a; 设计背景&#xff1a; 解决方案&#xff1a; 测试工具使用loadrunner脚本编写&#xff0c;这样的好处是 控制指令说明&#xff1a; 自定义检查方法说明&#xff1a; 变量说明&#xff1a; 附加动作说明&#xff1a; 前言&#xff1a; 自动化回归测试工…

Numpy---ndarray矩阵运算、广播机制、排序、文件操作

1. 矩阵运算 n 10 # 加 n - 10 # 减 n * 10 # 乘 n / 10 # 除 n // 2 # 整除 n ** 2 # 次方 n % 2 # 余数 n1 np.random.randint(0, 10, size(4, 5)) n2 np.random.randint(0, 10, size(4, 5)) display(n1, n2) array([[3, 6, 1, 9, 9],[8, 9, 2, 0, 4],[4, 8, 5, …

17 条件随机场

文章目录 17 条件随机场——CRF&#xff08;Condition Random Field&#xff09;17.1 背景介绍17.2 HMM与MEMM的区别17.3 MEMM与CRF的区别17.4 CRF模型17.4.1 CRF的概率密度函数17.4.2 CRF概率密度函数简化&#xff08;向量形式&#xff09; 17.5 CRF需要解决的问题17.6 边缘概…