【LeetCode】排序数组——不一样的方式实现快排

news2024/11/16 10:26:21

目录

题目链接 

颜色分类

算法原理

代码实现

排序数组 

算法原理

代码实现

最小的k个数

算法原理

代码实现 


题目链接 

LeetCode链接:75. 颜色分类 - 力扣(LeetCode)

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

LeetCode链接:面试题 17.14. 最小K个数 - 力扣(LeetCode)

颜色分类

算法原理

我们可以将这个数组划分为三个区域,左边区域全是0也就是红色,中间区域全是1也就是白色,右边区域全是2也就是蓝色。因此我们可以用个变量i来遍历数组,变量left标记0(红色)区域的最右侧,变量right标记2(蓝色)区域的最左侧。

那么就会形成下图所示区域

  • [0, left]:全都是0
  • [left + 1, i - 1]:全都是1
  • [i, right - 1]:全都是待遍历的元素
  • [right, n - 1]:全都是2

在遍历数组的时候分情况讨论

  • 当nums[i] == 0时:我们需要将 i 位置的元素和 left + 1位置的元素进行交换,这样就能保证在left的左边都是0(包括left),,交换完后i向后移动,swap(nums[++left], nums[i++]。
  • 当nums[i] == 1时:直接i++,这样就能保证left + 1到i这个区域内都是1。
  • 当nums[i] == 2时:我们需要将 i 位置的元素和 right - 1位置的元素进行交换,这样就能保证在right的右边都是2(包括right),此时的 i 不需要移动,因为 i 到 right - 1 的这块区域都是待遍历的元素,交换后还是待遍历的元素。swap(nums[--right], nums[i])。

当i >= right时停止遍历 

代码实现

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int i = 0, n = nums.size();
        int left = -1, right = n;
        while(i < right)
        {
            if(nums[i] == 0)
            {
                swap(nums[++left], nums[i++]);
            }
            else if(nums[i] == 1)
            {
                i++;
            }
            else
            {
                swap(nums[--right], nums[i]);
            }
        }
    }
};

排序数组 

 

算法原理

 和上面颜色分类的思想是一样的,将数组划分为三块区域,左边区域为小于key的,中间区域为等于key的,右边区域为大于key的。

分类讨论:

  • 当nums[i] < key时:我们需要将 i 位置的元素和 left + 1 位置的元素进行交换,这样就能保证在left的左边全都是比key小的数(包括left),交换完后i向后移动,swap(nums[++left], nums[i++]。
  • 当nums[i] == key时:直接i++,这样就能保证left + 1到i这个区域内都是等于key的。
  • 当nums[i] > key时:我们需要将 i 位置的元素和 right - 1位置的元素进行交换,这样就能保证在right的右边都是大于key的(包括right),此时的 i 不需要移动,因为 i 到 right - 1 的这块区域都是待遍历的元素,交换后还是待遍历的元素。swap(nums[--right], nums[i])。

小优化:可以选择随机的方式来选择key值,至于为什么可以去看看算法导论这本书,里面给出了详细证明。 

代码实现

class Solution {
public:
    vector<int> sortArray(vector<int>& nums) {
        srand(time(nullptr));
        qsort(nums, 0, nums.size() - 1);
        return nums;
    }
    void qsort(vector<int>& nums, int l, int r)
    {
        if(l >= r) return;

        int key = getRandom(nums, l, r);//随机取key值
        //分三块区域
        int i = l, left = l - 1, right = r + 1;
        while(i < right)
        {
            if(nums[i] < key) swap(nums[++left], nums[i++]);
            else if(nums[i] == key) i++;
            else swap(nums[--right], nums[i]);
        }

        //递归
        qsort(nums, l, left);
        qsort(nums, right, r);
    }

    int getRandom(vector<int>& nums, int left, int right)
    {
        int r = rand();
        return nums[r % (right - left + 1) + left];
    }
};

最小的k个数

 

算法原理

 原理和上面的排序数组一样,只是在最后要进行讨论一下k的大小

分类讨论:

  • 如果c >= k:k是落在大于key的这个区域内,只需递归这个区域找出key即可。
  • 如果b + c >= k:直接返回key就行了,因为k就落在了等于key的这个区域内。
  • 如果上面两种情况都不满足,那说明k落在了小于key这个区域内,只需找k - b - c(要把前面两个的区域去掉)大的并且递归这个区域即可。

代码实现 

class Solution {
public:
    int getRandom(vector<int>& arr, int left, int right)
    {
        return arr[rand() % (right - left + 1) + left];
    }
    void qsort(vector<int>& arr, int l, int r, int k)
    {
        if(l >= r) return;

        int key = getRandom(arr, l, r);
        int i = l, left = l - 1, right = r + 1;
        while(i < right)
        {
            if(arr[i] < key) swap(arr[++left], arr[i++]);
            else if(arr[i] == key) i++;
            else swap(arr[--right], arr[i]);
        }

        int a = left - l + 1, b = right - left - 1;
        if(a >= k) qsort(arr, l, left, k);
        else if(a + b >= k) return;
        else qsort(arr, right, r, k - a - b);
    }
    vector<int> smallestK(vector<int>& arr, int k) {
        srand(time(nullptr));
        qsort(arr, 0, arr.size() - 1, k);
        return {arr.begin(), arr.begin() + k};
    }
};

今天的内容就分享到这里了,如果内容有错,有写的不好的地方,还望告知,谢谢!!!

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

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

相关文章

零基础如何闯入IT的神秘大门?

前言 随着信息技术的飞速发展&#xff0c;IT行业成为了许多有志之士梦寐以求的职业领域。但对于零基础的人来说&#xff0c;如何成功进入这个行业却是一个不小的挑战。下面&#xff0c;我将结合自身的C语言专业知识&#xff0c;为大家详细阐述一条可行的学习路径&#xff0c;并…

【MySQL】游标和触发器

一、游标 1.1 什么是游标 1、使用背景 在我们使用update或者delete操作数据时&#xff0c;一般都会根据条件语句查询出很多条记录组成的数据集&#xff0c;然后一次性批量操作 假设我们想要对这个结果集中的数据 一行一行的进行操作&#xff0c;比如某个条件满足后&#xff…

Redis安装及基本类型详解

目录 一、Redis概念 二、Redis的应用场景 三、Redis的特点 四、redis访问数据为什么快&#xff1f; 五、Ubuntu下安装redis 五、全局命令(针对任意类型value都可使用) 1、keys &#xff08;1&#xff09;keys * &#xff08;2&#xff09;keys pattern 2、exists 3、…

从0到1搭建文档库——sphinx + git + read the docs

sphinx git read the docs 目录 一、sphinx 1 sphinx的安装 2 本地构建文件框架 1&#xff09;创建基本框架&#xff08;生成index.rst &#xff1b;conf.py&#xff09; conf.py默认内容 index.rst默认内容 2&#xff09;生成页面&#xff08;Windows系统下&#xf…

uniapp vue2 时钟 循环定时器

效果展示&#xff1a; 时钟 写在前面&#xff1a;vue2有this指向&#xff0c;没有箭头函数 实验操作&#xff1a;封装一个时钟组件 uniapp vue2 封装一个时钟组件 核心代码&#xff1a; this指向的错误代码&#xff0c;在下&#xff1a; start() { this.myTimer setInterval(…

11.内建函数对象_算数、关系、逻辑仿函数

文章目录 算数仿函数代码工程运行结果 关系仿函数代码工程运行结果 逻辑仿函数代码工程运行结果 算数仿函数 需要添加#include<functional>头文件使用 代码工程 #define _CRT_SECURE_NO_WARNINGS #include<iostream> #include<functional>using namespace…

顶象全系列产品升级,对抗AI带来的新威胁

4月2日&#xff0c;在顶象CSDN直播间&#xff0c;最新一期“业务安全大讲堂”上&#xff0c;顶象数据科学家翼龙与资深解决方案专家鳯羽&#xff0c;围绕当前备受关注的AI威胁、人脸风险进行深入分享&#xff0c;并详细介绍针对AI威胁的最新反欺诈技术与安全产品。 AI威胁带来的…

开发项目接单报价快速计算,报价量化程序

定制化开发&#xff0c;如何计算项目预算&#xff0c;是程序开发者头疼的一个问题。 项目费用谈得过低&#xff0c;就天天加班累死赚不到钱&#xff1b;谈得过高&#xff0c;会导致顾客流失&#xff0c;信誉受损。 项目费用量化可见是多么重要。 下面是一段量化的程序&#…

【教程】VOC数据集制作

语义分割任务中VOC数据集的制作&#xff0c;任务中只有一种标签&#xff1a;gas 文章目录 1、由黑白图像识别为txt标签2、txt转json3、数据集转VOC格式 1、由黑白图像识别为txt标签 由于使用CycleGAN网络进行风格迁移学习&#xff0c;生成了大量伪标签图像&#xff0c;因此需…

阿里云ICP备案工信部短信核验详细流程,1分钟搞定教程!

网站ICP备案或APP备案通过云厂商的备案初审后&#xff0c;需要在工信部完成短信核验操作&#xff0c;本文云服务器吧yunfuwuqiba.com以阿里云备案为例&#xff0c;来详细说明工信部短信核验详细流程&#xff0c;非常简单&#xff1a; 阿里云备案提交到阿里云初审&#xff0c;初…

学习操作系统之OS的作用

OS是用户与计算机硬件之间的接口 OS处于用户和硬件系统之间,用户通过OS来使用计算机硬件系统.即用户可以在OS的帮助下方便、快捷、可靠的操作计算机硬件和运行自己的程序。 下图是我对于操作系统的简单理解 OS是计算机系统资源的管理者 一个计算机系统包含四类硬件资源&…

angular—mooc课学习笔记

1.angular工程目录 2.设置标签元素样式 3.fex布局 4.事件绑定 5. 双向数据传输 6. 键盘实现方法 7.内置指令拉选框 8. ngFor指令

RocketMQ建Topic

# 查看集群状况 ./mqadmin clusterList -n localhost:9876 # 创建topic ./mqadmin updateTopic -b localhost:10911 -t my_topic -n localhost:9876 # 查看所有topic ./mqadmin topicList -n localhost:9876参考 Admin Tool

ESP32S3网络编程学习笔记(1)—— Wi-Fi扫描实验

前言 &#xff08;1&#xff09;如果有嵌入式企业需要招聘湖南区域日常实习生&#xff0c;任何区域的暑假Linux驱动/单片机/RTOS的实习岗位&#xff0c;可C站直接私聊&#xff0c;或者邮件&#xff1a;zhangyixu02gmail.com&#xff0c;此消息至2025年1月1日前均有效 &#xff…

计算机服务器中了helper勒索病毒怎么办,helper勒索病毒解密流程步骤

随着网络技术在企业中的不断应用&#xff0c;越来越多的企业离不开网络&#xff0c;网络为企业提供了极大便利&#xff0c;大大提升了生产运营效率&#xff0c;由此而产生的网络数据安全问题也成为了企业关心的主要话题。近期&#xff0c;云天数据恢复中心接到多家企业的求助&a…

在虚拟机尝试一次用启动盘重装系统

在虚拟机尝试一次用启动盘重装系统 没有自己重装过系统&#xff0c;也不敢对自己的笔记本下手&#xff0c;用虚拟机重装玩玩试试。 先设置成u盘启动 从boot中选择相应的创建的硬盘即可&#xff08;刚刚突然发现图片不能上传了&#xff0c;经过乱七八糟的尝试后&#xff0c;开一…

90天玩转Python—06—基础知识篇:Python中的七大基础数据类

90天玩转Python系列文章目录 90天玩转Python—01—基础知识篇:C站最全Python标准库总结 90天玩转Python--02--基础知识篇:初识Python与PyCharm 90天玩转Python—03—基础知识篇:Python和PyCharm(语言特点、学习方法、工具安装) 90天玩转Python—04—基础知识篇:Pytho…

js的qq换肤效果

文章目录 1. 演示效果2. 分析思路3. 代码实现3.1. 方式一3.2. 方式二3.3. 整体代码 1. 演示效果 2. 分析思路 先编写样式&#xff0c;弄好布局和排版。遍历这个集合&#xff0c;对每个图片元素&#xff08;img&#xff09;添加一个点击事件监听器。可以使用 for 或者 forEach …

计算机毕业设计java 基于Android的拼图游戏app

当今社会&#xff0c;随着电子信息技术的发展&#xff0c;电子游戏也成为人们日常生活的一部分。这种娱乐方式结合了日新月异的技术&#xff0c;在游戏软件中结合了多种复杂技术。拼图游戏流行在各种电子产品上&#xff0c;从计算机&#xff0c;掌上游戏机到如今的手机&#xf…

番茄 短abogus补环境

声明: 本文章中所有内容仅供学习交流使用&#xff0c;不用于其他任何目的&#xff0c;抓包内容、敏感网址、数据接口等均已做脱敏处理&#xff0c;严禁用于商业用途和非法用途&#xff0c;否则由此产生的一切后果均与作者无关&#xff01;wx a15018601872 本文章…