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

目录

题目链接 

颜色分类

算法原理

代码实现

排序数组 

算法原理

代码实现

最小的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.mzph.cn/news/799312.shtml

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

相关文章

docker 部署 Epusdt - 独角数卡 dujiaoka 的 usdt 支付插件

部署 部署说明 部署之前必须注意的几点事项,该教程不一定适合所有用户: 本教程主要是使用 docker 部署,宝塔用户或宿主机直接安装的用户请直接参考官网教程.本教程是独立部署 epusdt,使用独立的mysql和redis,与dujiaoka项目分开. 在研究的过程中发现 epusdt 也需要用到 mys…

CADP加密系统的可扩展性和可定制性

CADP加密系统是一种专门用于保护CAD(计算机辅助设计)文件安全的加密解决方案。随着CAD技术在各个领域的广泛应用&#xff0c;CAD文件的安全性和保密性日益受到重视。CADP加密系统通过一系列先进的加密技术和安全措施&#xff0c;为CAD文件提供全面的保护&#xff0c;防止未经授…

微信小程序脚本的执行顺序

在小程序中的脚本执行顺序和浏览器中有所不同。 小程序的执行的入口文件是 app.js 。 并且会根据其中 require 的模块顺序决定文件的运行顺序&#xff0c;代码是一个 app.js 示例。 app.js /* a.js console.log(a.js) */ var a require(./a.js) console.log(app.js)/* b.js co…

ES入门十五:分页的三驾马车【from+size、search after、scroll api】

从数据集中获取数据时分页是绕不开的操作&#xff0c;一下子从数据集中获取过多的数据可能会造成系统抖动、占用带宽等问题。特别是进行全文搜索时&#xff0c;用户只关心相关性最高的那个几个结果&#xff0c;从系统中拉取过多的数据等于浪费资源。 ES提供了3种分页方式&…

Java | Leetcode Java题解之第15题三数之和

题目&#xff1a; 题解&#xff1a; class Solution {public List<List<Integer>> threeSum(int[] nums) {int n nums.length;Arrays.sort(nums);List<List<Integer>> ans new ArrayList<List<Integer>>();// 枚举 afor (int first 0;…

springboot整合ShardingSphere分库分表并插入1kw条记录

目录 一&#xff0c;数据分片 二&#xff0c;水平分片 三&#xff0c;创建数据库表 四&#xff0c;springboot项目导入依赖 五&#xff0c;创建类 六&#xff0c;bug bug放到最后了。 一&#xff0c;数据分片 数据分片指按照某个维度将存放在单一数据库中的数据分散地存…

数据结构 实验报告11

一、实验目的和要求 目的&#xff1a;熟悉后序线索二叉树并实现后序遍历 要求&#xff1a; &#xff08;1&#xff09;创建二叉树。 &#xff08;2&#xff09;转换为后序线索二叉树。 &#xff08;3&#xff09;实现后序遍历的非递归算法。 二、实验环境 编译器&#xf…

每天学习一个Linux命令之curl

每天学习一个Linux命令之curl 在Linux系统中&#xff0c;有很多有用的命令可以帮助我们与网络进行交互。一个非常常用的命令是curl&#xff0c;它是一个功能强大的工具&#xff0c;可用于发送、接收和处理各种网络请求。本文将详细介绍在Linux下使用curl命令的各种选项及其用法…

如何理解图像处理领域的病态问题(ill-posed problem)

ill-posed problem&#xff0c;我们可以理解为病态问题或者不适定问题。在本文中&#xff0c;统一成为不适定问题。 在讨论不适定问题&#xff08;ill-posed problem&#xff09;之前&#xff0c;我们先来看一下什么叫适定性问题&#xff08;well-posed problem&#xff09;。…

如何明确的选择IT方向?

一、明确目标 作为初学者&#xff0c;先树立自己目标&#xff0c;找到自己感兴趣的IT行业&#xff0c;IT行业分很多种&#xff0c;听的最多次的无非不就是web前端工、程序员、后端、大数据、网络运维等。学习知识也是为了找到更好的工作&#xff0c;所以我建议先去boss直聘、五…

浅谈Mysql(四)——Mysql知识补充

一、mysql什么时候会锁表 MySQL中的查询语句通常不会锁表&#xff0c;因为查询操作只读取数据而不修改数据。然而&#xff0c;当执行某些特定的查询语句或者在特定情况下&#xff0c;MySQL可能会对表进行锁定以保证数据的一致性和完整性。以下是几种可能导致表锁定的情况&#…

目标检测标签分配策略,难样本挖掘策略

在目标检测任务中&#xff0c;样本的划分对于模型的性能具有至关重要的影响。其中&#xff0c;正样本指的是包含目标物体的图像或区域&#xff0c;而负样本则是不包含目标物体的图像或区域。然而&#xff0c;在负样本中&#xff0c;有一部分样本由于其与正样本在特征上的相似性…

jest单元测试——项目实战

jest单元测试——项目实战 一、纯函数测试二、组件测试三、接口测试四、React Hook测试&#x1f4a5; 其他的疑难杂症另&#xff1a;好用的方法 &#x1f31f; 温故而知新&#xff1a;单元测试工具——JEST 包括&#xff1a;什么是单元测试、jest的基本配置、快照测试、mock函数…

机器学习工作流

本文的目的是演示如何构建一个相对完整的机器学习工作流 1.首先对工程进行基本的参数配置 # 进行建模基本配置 SCORE_EVA roc_auc random_state_clf 1 n_jobs 4 cv_split StratifiedKFold(n_splits5, shuffleTrue, random_state1) cv_split2 StratifiedKFold(n_splits5, …

(013)window的Idea运行程序 Amazon java.nio.file.AccessDeniedException

解决方法一 在资源管理器中删除该目录&#xff0c; 在程序中使用代码&#xff0c;重新建立该目录&#xff1a; if (!FileUtil.exist(destinationPath)){FileUtil.mkdir(destinationPath); }解决方法二 JDK 的版本有问题&#xff0c;换个JDK。 解决方法三 网络不好&#xf…

「39」打造专业流畅的直播特效转场……

「39」工作室模式 打造专业流畅的直播特效转场体验 工作室模式是OBS软件里的一个特殊功能,用于后期直播过程中追求直播效果的用户,才会使用此功能。 该功能意在更加平滑,使用模板信息变化的过渡效果。主要用在赛事比分、活动抽奖、直播时需要经常更改的场景和内容,以及片…

Spring之底层架构核心概念解析

你好&#xff0c;我是柳岸花开。 在当今快速发展的软件开发领域&#xff0c;各种技术层出不穷&#xff0c;但有一项技术以其卓越的设计、灵活的配置和广泛的应用&#xff0c;始终屹立在开发者的工具箱中——这就是Spring框架。自2003年首次发布以来&#xff0c;Spring已经成为J…

Android 11属性系统初始化流程

在init进程启动的第二阶段&#xff0c;调用PropertyInit 对属性系统进行初始化 int SecondStageMain(int argc, char** argv) {//省略PropertyInit();//省略 }PropertyInit函数在system\core\init\property_service.cpp 中实现 void PropertyInit() {//省略mkdir("/dev/…

opencv x86(32位) windows下vs2019编译问题

opencv x86(32位) windows下vs2019编译相关资料很多&#xff0c;都特别受用。例如 - https://blog.csdn.net/m0_59025104/article/details/134109081 - https://blog.csdn.net/sements/article/details/108410470 但是&#xff0c;自己编译时候仍遇到一些问题&#xff0c;例如&…

智能网联汽车自动驾驶数据记录系统DSSAD数据元素

目录 第一章 数据元素分级 第二章 数据元素分类 第三章 数据元素基本信息表 表1 车辆及自动驾驶数据记录系统基本信息 表2 车辆状态及动态信息 表3 自动驾驶系统运行信息 表4 行车环境信息 表5 驾驶员操作及状态信息 第一章 数据元素分级 自动驾驶数据记录系统记录的数…