【分支-快速排序】

【分支-快速排序】

  • 1. 颜色分类
    • 1.1 题目来源
    • 1.2 题目描述
    • 1.3 题目解析
  • 2. 排序数组
    • 2.1 题目来源
    • 2.2 题目描述
    • 2.3 题目解析
  • 3. 数组中的第K个最大元素
    • 3.1 题目来源
    • 3.2 题目描述
    • 3.3 题目解析
  • 4. 库存管理 III
    • 4.1 题目来源
    • 4.2 题目描述
    • 4 .3 题目解析

1. 颜色分类

1.1 题目来源

75. 颜色分类

1.2 题目描述

给定一个包含红色、白色和蓝色、共 n 个元素的数组 nums ,原地 对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。

我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。

必须在不使用库内置的 sort 函数的情况下解决这个问题。

  1. 示例 1:
    输入:nums = [2,0,2,1,1,0]
    输出:[0,0,1,1,2,2]
  2. 示例 2:
    输入:nums = [2,0,1]
    输出:[0,1,2]

提示:
n == nums.length
1 <= n <= 300
nums[i] 为 0、1 或 2

1.3 题目解析

方法一:使用快速排序

这里就是简单的一个快排模板了.

class Solution {
public:void QuickSortHoare(vector<int>& a, int left, int right){if (left >= right)return;int l = left, r = right;int key = left;while (l < r){while (l < r && a[r] >= a[key]) // 这里要注意了一定要写等号,也必须是r先--在l++r--;while (l < r && a[l] <= a[key])l++;swap(a[l], a[r]);}swap(a[left], a[l]);QuickSortHoare(a, left, l - 1);QuickSortHoare(a, l + 1, right);}void sortColors(vector<int>& nums) {QuickSortHoare(nums, 0, nums.size() - 1);}
};

方法二:三指针

我们可以将整个数组分成三部分呢,第一部分全部是0,第二部分全部都是1,第三部分全部都是2。于是我们可以定义三个指针,left,cur,right,left代表第一部分的最右边,right代表第三部分的最左边,cur指针用于遍历整个数组。这样的话我们就可以得到一个范围,即[left,l]为第一部分,[l + 1, r - 1]是第二部分,[r, right]是第三部分。

这里的解题思路可以参考移动零。

所以我们就可以得到三个部分:

  1. 如果nums[cur] == 0 ,就swap(nums[cur], nums[left + 1],同时将left和cur都进行++
  2. 如果nums[cur] == 1,则cur直接进行++
  3. 如果num[cur] == 2,则swap(nums[cur], nums[right - 1]),同时right进行–,这个时候cur不需要进行++,因为right - 1下标对应的数据是还没有进行判断的,有可能是0,有可能是1,也有可能是2,是不确定的,所以还需要进行判断。
class Solution {
public:void sortColors(vector<int>& nums) {int n = nums.size();int left = -1 , right = n;int cur = 0;while (cur < right){if (nums[cur] == 0){swap(nums[left + 1], nums[cur]);left++;cur++;}else if (nums[cur] == 1){cur++;}else{swap(nums[right - 1],nums[cur]);right--;}}}
};

2. 排序数组

2.1 题目来源

912. 排序数组

2.2 题目描述

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

  1. 示例 1:
    输入:nums = [5,2,3,1]
    输出:[1,2,3,5]
  2. 示例 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

2.3 题目解析

方法一:快排模板

直接使用快排模板,这里需要注意了int key = a[(left + right) >> 1];必须写成key直接拿到值,不能使用通过拿到下标的方式int key = (left + right) >> 1,然后后序使用while (a[r] > a[key])这样通过索引的方式进行判断,因为可能在整个whiel(l < r)的阶段中key所对应下标的值会发生改变。只有一开始拿到索引对应的值后继续使用方可。

class Solution {
public:void _sort(vector<int>& a, int left, int right){if (left >= right) return;int l = left, r = right;int key = a[(left + right) >> 1];while (l <= r){while (a[r] > key)r--;while (a[l] <key)l++;if (l <= r){swap(a[l], a[r]);l++;r--;}}_sort(a, left, r);_sort(a, l, right);}vector<int> sortArray(vector<int>& nums) {_sort(nums, 0, nums.size() - 1);return nums;}
};

方法二:使用三指针+随机取key值

向上面那样如果直接使用快排的模板的话,如果是全部都是相同的数,或者这个数组本身就是一个有序的话,那么直接使用快排模板的话时间复杂度将会达到O(N^2)所以我们可以对快排进行优化。同样的我们也可以划分为三部分,第一部分是小于key(基准值)的,第二部分是等于key的,第三部分是大于key的。于是我们可以定义三个指针,left,cur,right,left代表第一部分的最右边,right代表第三部分的最左边,cur指针用于遍历整个数组。这样我们递归只需要对范围为[left, l]和[r, right]范围之间进行递归了。[l+ 1, r - 1]这个区间的范围是不用在进行递归了。而至于key的选取的话,我们之前都是采用第一个或者最后一个或者中间为基准值,这里我们使用使用随机选取的方式。

于是我们就可以得出这样的结论:

  1. 如果nums[cur] < key,则执行swap(nums[left + 1], nums[cur]),同时对left和cur进行++
  2. 如果nums[cur] == key,则只需要对cur进行++即可。
  3. 如果nums[cur] > key,则执行swap(nums[right - 1], nums[cur]),同时只需要对right–即可,cur不需要进行操作,因为被交换过去的nums[right - 1]是还没进行处理的,所以还需要进一步处理。

所以上述这个优化可以将时间复杂度优化接近到NlogN的时间复杂度。

class Solution {
public:void _sort(vector<int>& nums, int left, int right){if (left >= right) return;int l = left - 1, r = right + 1; // 这样处理可以提高代码复用度int key = nums[rand() % (right - left + 1) + left];int cur = left;while (cur < r){if (nums[cur] < key){swap(nums[l + 1], nums[cur]);l++;cur++;}else if(nums[cur] == key){cur++;}else{swap(nums[r - 1], nums[cur]);r--;}}_sort(nums, left, l);_sort(nums, r, right);}vector<int> sortArray(vector<int>& nums) {_sort(nums, 0, nums.size() - 1);return nums;}
};

3. 数组中的第K个最大元素

3.1 题目来源

215.数组中的第K个最大元素

3.2 题目描述

给定整数数组 nums 和整数 k,请返回数组中第 k 个最大的元素。

请注意,你需要找的是数组排序后的第 k 个最大的元素,而不是第 k 个不同的元素。

你必须设计并实现时间复杂度为 O(n) 的算法解决此问题。

  1. 示例 1:
    输入: [3,2,1,5,6,4], k = 2
    输出: 5
  2. 示例 2:
    输入: [3,2,3,1,2,4,5,5,6], k = 4
    输出: 4

提示:
1 <= k <= nums.length <= 105
-104 <= nums[i] <= 104

3.3 题目解析

方法一:使用快排模板:

class Solution {
public:void _sort(vector<int>& nums, int left, int right){if (left >= right) return;int l = left, r = right;int key = nums[(left + right) >> 1];while (l <= r){while (nums[r] > key)r--;while (nums[l] < key)l++;if (l <= r){swap(nums[l], nums[r]);l++;r--;}}_sort(nums, left, r);_sort(nums, l, right);}int findKthLargest(vector<int>& nums, int k) {_sort(nums, 0, nums.size() - 1);return nums[nums.size() - k];}
};

方法二:使用三指针数据分三块+随机选取基准值

这里其实和上面几题是一样的方法,也是将数组分成三份,第一部分小于key,第二部分等于key,第三部分大于key。使用三个指针来操作,left,cur,right。left代表第一部分的最右边,right代表第三部分的最左边,cur指针用于遍历整个数组。我们假设第一部分也就是[left, l]的长度是a,第二部分也就是[l + 1, r - 1]的长度是b,第三部分也就是[r, right]的长度是c。现在我们要找到第k大的元素。所以就有一下结论

在这里插入图片描述
所以我们可以得出一下结论:

  1. 如果c >= k,则直接在[r, right]中查找就可以了
  2. 如果 c + b >= k,则直接就是返回[l + 1, r - 1] 中的任意一个值就行。
  3. 如果上述1和2都不满足则需要在[left, l]中进行查找,而这个时候要查找的因该是第(k- b - c)大的数了。
class Solution {
public:int _sort(vector<int>& nums, int left, int right, int k){int l = left - 1, r = right + 1;int key = nums[rand()%(right - left + 1) + left];int cur = left;while (cur < r){if(nums[cur] < key){swap(nums[l + 1], nums[cur]);l++;cur++;}else if (nums[cur] == key){cur++;}else{swap(nums[r - 1], nums[cur]);r--;}}if (right - r + 1 >= k){return _sort(nums, r, right, k);}else if (right - l >= k){return nums[l + 1];}else{int c = right - r + 1;int b = r - l - 1;return _sort(nums, left, l, k - b - c);}}int findKthLargest(vector<int>& nums, int k) {return _sort(nums, 0, nums.size() - 1, k);}
};

4. 库存管理 III

4.1 题目来源

159. 库存管理 III

4.2 题目描述

仓库管理员以数组 stock 形式记录商品库存表,其中 stock[i] 表示对应商品库存余量。请返回库存余量最少的 cnt 个商品余量,返回 顺序不限。

  1. 示例 1:
    输入:stock = [2,5,7,4], cnt = 1
    输出:[2]
  2. 示例 2:
    输入:stock = [0,2,3,6], cnt = 2
    输出:[0,2] 或 [2,0]

提示:
0 <= cnt <= stock.length <= 10000
0 <= stock[i] <= 10000

4 .3 题目解析

这题其实也是使用一样的方法,使用三指针数据分三块+随机选取基准值。

class Solution {
public:void _sort(vector<int>& nums, int left, int right){if (left >= right) return;int l = left - 1, r = right + 1;int key = nums[rand() % (right - left + 1) + left];int cur = left;while (cur < r){if (nums[cur] < key){swap(nums[l + 1], nums[cur]);l++;cur++;}else if (nums[cur] == key){cur++;}else{swap(nums[r - 1], nums[cur]);r--;}}_sort(nums, left, l);_sort(nums, r, right);}vector<int> inventoryManagement(vector<int>& stock, int cnt) {vector<int> v;if (cnt == 0) return v;_sort(stock, 0, stock.size() - 1);for (int i = 0; i < cnt; i++){v.push_back(stock[i]);}return v;}
};

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

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

相关文章

如何使用QT完成记事本程序的UI界面布局

每日QT技巧查询表-CSDN博客 会持续更新记事本编写的全部过程&#xff0c;关注不迷路 一、相关控件 ①水平和垂直布局 ②按键 ③文本框 ④水平弹簧 ⑤标签 ⑥Widget 二、控件使用方法 1、PushButton 拖出三个按键&#xff0c;并对其进行命名&#xff0c;两处地方命名可以不一…

数据结构——线性表(顺序存储结构和单链表结构)

线性表的定义 线性表&#xff08;List&#xff09;&#xff1a;由零个或多个数据元素组成的有限序列。 &#xff08;1&#xff09;它是一个序列&#xff0c;也就是元素之间有个先来后到的&#xff1b; &#xff08;2&#xff09;若元素有多个&#xff0c;则第一个元素无前驱…

[数据集][目标检测]人脸口罩佩戴目标检测数据集VOC+YOLO格式8068张3类别

数据集格式&#xff1a;Pascal VOC格式YOLO格式(不包含分割路径的txt文件&#xff0c;仅仅包含jpg图片以及对应的VOC格式xml文件和yolo格式txt文件) 图片数量(jpg文件个数)&#xff1a;8068 标注数量(xml文件个数)&#xff1a;8068 标注数量(txt文件个数)&#xff1a;8068 标注…

Spring Boot实现文件上传和下载

1.背景 项目中经常会有上传和下载的需求&#xff0c;这篇文章简述一下springboot项目中实现简单的上传和下载。 2.代码工程 实验目标 实现简单的文件上传和下载 pom.xml <?xml version"1.0" encoding"UTF-8"?> <project xmlns"http://…

JDBC:连接数据库

文章目录 报错 报错 Exception in thread “main” java.sql.SQLException: Can not issue SELECT via executeUpdate(). 最后这里输出的还是地址&#xff0c;就是要重写toString()方法&#xff0c;但是我现在还不知道怎么写 修改完的代码&#xff0c;但是数据库显示&#…

Android 10.0 mtk平板camera2横屏预览旋转90度横屏拍照图片旋转90度功能实现

1.前言 在10.0的系统rom定制化开发中,在进行一些平板等默认横屏的设备开发的过程中,需要在进入camera2的 时候,默认预览图像也是需要横屏显示的,在上一篇已经实现了横屏预览功能,然后发现横屏预览后,拍照保存的图片 依然是竖屏的,所以说同样需要将图片也保存为横屏图标…

第三次去银行办事,核心是犯了抓不住重点这个毛病

手机银行不小心输错了两次密码&#xff0c;然后就限制了交易&#xff0c;只能在柜台操作。 由此引发了比如提示密码错误、定期转活期、转账等功能的异常。 前两次去银行&#xff0c;竟然只是去解决了这些附带问题。 核心问题是限制非柜面交易啊。 哎 这就是抓不住重点&…

2024年9月最新界面:自己如何在电脑上注册新的Google谷歌账号,图文详解和关键点解析、常见问题

有一些朋友需要通过谷歌账号来工作、学习或娱乐&#xff08;例如很多游戏需要用谷歌账号来注册和使用&#xff09;&#xff0c;但是不知道如何注册谷歌账号&#xff0c;或者知道如何注册&#xff0c;但是对于一些步骤或者注意事项不太熟悉&#xff0c;导致注册不成功&#xff0…

web群集--nginx配置文件location匹配符的优先级顺序详解及验证

文章目录 前言优先级顺序优先级顺序(详解)1. 精确匹配&#xff08;Exact Match&#xff09;2. 正则表达式匹配&#xff08;Regex Match&#xff09;3. 前缀匹配&#xff08;Prefix Match&#xff09; 匹配规则的综合应用验证优先级 前言 location的作用 在 NGINX 中&#xff0…

证书学习(四)X.509数字证书整理

目录 一、X.509证书 介绍1.1 什么是 X.509证书?1.2 什么是 X.509标准?1.3 什么是 PKI?二、X.509证书 工作原理2.1 PKI 的基础——加密算法2.2 PKI 证书编码三、X.509证书 结构3.1 证书字段3.2 证书扩展背景: 我们在日常的开发过程中,经常会遇到各种各样的电子证书文件,其…

Ubuntu: 配置OpenCV环境

从从Ubuntu系统安装opencv_ubuntu安装opencv-CSDN博客文章浏览阅读2.3k次&#xff0c;点赞4次&#xff0c;收藏14次。开源计算机视觉(OpenCV)是一个主要针对实时计算机视觉的编程函数库。OpenCV的应用领域包括:2D和3D功能工具包、运动估计、面部识别系统、手势识别、人机交互、…

vue通过html2canvas+jspdf生成PDF问题全解(水印,分页,截断,多页,黑屏,空白,附源码)

前端导出PDF的方法不多&#xff0c;常见的就是利用canvas画布渲染&#xff0c;再结合jspdf导出PDF文件&#xff0c;代码也不复杂&#xff0c;网上的代码基本都可以拿来即用。 如果不是特别追求完美的情况下&#xff0c;或者导出PDF内容单页的话&#xff0c;那么基本上也就满足业…

ChatGPT+Simple Mind Map生成思维导图:快速提升学习效率

一、告别杂乱笔记&#xff0c;一键生成清晰思维导图&#xff01; 最近开始学习网络安全&#xff0c;一头扎进了各种协议、漏洞、防御机制的海洋中。信息量巨大&#xff0c;知识点零散&#xff0c;让我很快便陷入了“知识焦虑”——笔记越记越多&#xff0c;却越来越混乱&#…

第50课 Scratch入门篇:放烟花

放烟花 故事背景: 水在一个宁静的小镇上,生活着一位充满好奇心和创造力的小朋友。   有一天晚上,小镇的天空格外黑暗,星星也躲在了云层后面。小朋友望着黑漆漆的夜空,心想:要是能有一场绚丽的烟花表演,那该多好啊!于是,他决定用自己所学的 Scratch 编程知识来创造一…

通过域名无法访问不到网站,IP可正常访问(DNS污染)

一 DNS被污染 就在刚刚突然访问不到csdn&#xff0c;域名无法访问如下图&#xff1a; 确认DNS是否解析有问题 1 ping 域名 先ping一下域名&#xff0c;ping 域名后得到ip, ping通了如下图&#xff1a; 2 使用IP访问测试 通过ip再访问网站&#xff0c;ip可以正常访问如下图&…

.NetCore+vue3上传图片 Multipart body length limit 16384 exceeded.

实现目标。点击图片上传头像 效果图 前端部分图片上传关键代码 <div class"avatar-wrap"><el-imagestyle"width: 154px; height: 154px":src"form.headPic":fit"fit"/></div><div class"upload-box"…

vllm使用BitAndBytes量化模型失败

ValueError: BitAndBytes quantization with TP or PP is not supported yet 使用加载hf模型时&#xff0c;使用load_in_8bit来量化模型&#xff08;底层其实是调用bitsandbytes来量化&#xff09;&#xff1a; import argparse import os import torchdef parse_arguments()…

RP2040 C SDK RTC功能使用

RP2040 C SDK RTC功能使用 &#x1f4cd;《RP2040 C SDK串口功能使用》&#x1f955;RP2040 RTC API官方文档说明&#xff1a;https://www.raspberrypi.com/documentation/pico-sdk/hardware.html#group_hardware_rtc&#x1f955;官方例程参考&#xff1a;https://github.com/…

【MySQL】MySQL中表的增删改查——(基础篇)(超详解)

前言&#xff1a; &#x1f31f;&#x1f31f;本期讲解关于MySQL中CDUD的基础操作&#xff0c;希望能帮到屏幕前的你。 &#x1f308;上期博客在这里&#xff1a;http://t.csdnimg.cn/fNldO &#x1f308;感兴趣的小伙伴看一看小编主页&#xff1a;GGBondlctrl-CSDN博客 目录 …

【Python篇】详细学习 pandas 和 xlrd:从零开始

文章目录 详细学习 pandas 和 xlrd&#xff1a;从零开始前言一、环境准备和安装1.1 安装 pandas 和 xlrd1.2 验证安装 二、pandas 和 xlrd 的基础概念2.1 什么是 pandas&#xff1f;2.2 什么是 xlrd&#xff1f; 三、使用 pandas 读取 Excel 文件3.1 读取 Excel 文件的基础方法…