当前位置: 首页 > backend >正文

【分治】快速排序

文章目录

  • 912. 排序数组
  • 解题思路:分治

在这里插入图片描述

912. 排序数组

912. 排序数组

​ 给你一个整数数组 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 <= nums.length <= 5 * 104
  • -5 * 104 <= nums[i] <= 5 * 104

解题思路:分治

​ 我们在数据结构阶段学习的快速排序的思想可以知道,快排最核心的一步就是 Partition (分割数据):将数据按照⼀个标准,分成左右两部分。这种方法的缺点就是遇到大量重复的元素的时候,时间复杂度就相当于是 O(n^2) 了,并且做的都是无效的工作,以至于这道题的官方题解虽然使用的是分为左右两部分的方法,但是依然跑不过去。

​ 而如果我们使用 75. 颜色分类 问题的思想,将数组划分为 左 中 右 三部分:左边是比基准元素小的数据,中间是与基准元素相同的数据,右边是比基准元素大的数据。然后再去递归的排序左边部分和右边部分即可(可以舍去大量的中间重复部分),这 在处理数据量有很多重复的情况下,效率会大大提升

在这里插入图片描述

​ 首先我们得先确定一个能让数组划分的一个基准值,这里采用的是:随机方式选取基准值。这种方式在算法导论中用概率论的知识分析后发现使用该方式选取基准值的话,整个快排的时间复杂度是接近稳定在 O(n * logn) 的,已经是非常高效的了!

​ 其实这并不难,只需要使用接口 rand() 获取随机数,然后模上数组的元素个数即可,但是因为分治的时候研究的是数组中的不同区间,所以还要加上 left 才行,才能让得到的随机数落在以 left 开头的区间,然后返回这个基准值即可!

int random(vector<int>& nums, int left, int right)
{return nums[(rand() % (right - left + 1)) + left];  // 记得要加上left,才能得到落在left以后的区间基准值
}

​ 然后就是之前我们在 75. 颜色分类 学过的划分为三块区间的思想,只不过这里不同的是区间的要求不同罢了!这里就不再赘述了,具体细节可以参考那道题的题解,里面有详细说明,这里直接列出来结论:(下面假设基准值是 partition

在这里插入图片描述

​ 要注意的是,这里的 leftright 指针指的依然需要是指定区间的外面,如下图所示:

在这里插入图片描述

​ 最后遍历完一遍数组的 [left, right] 区间之后,因为中间的等于 partition 的区间就是固定好的了,相当于就是他们最终在数组中的位置已经找到了,此时 递归去排序左边小于 partition 的部分、右边大于 partition 的部分直到区间中 left ≥ right 就结束

class Solution {
public:int random(vector<int>& nums, int left, int right){// 记得要加上left,才能得到落在left以后的区间基准值return nums[(rand() % (right - left + 1)) + left]; }void quicksort(vector<int>& nums, int left, int right){// 终止条件if(left >= right)return;// 获取基准值int partition = random(nums, left, right);int i = left, l = left - 1, r = right + 1; // l和r需要从该区间的左右外边界开始while(i < r){if(nums[i] < partition)swap(nums[++l], nums[i++]);else if(nums[i] == partition)i++;elseswap(nums[--r], nums[i]);}// 递归左右部分,中间部分无需再处理quicksort(nums, left, l);quicksort(nums, r, right);}vector<int> sortArray(vector<int>& nums) {srand((unsigned int)time(nullptr));quicksort(nums, 0, nums.size() - 1);return nums;}
};

在这里插入图片描述

http://www.xdnf.cn/news/7334.html

相关文章:

  • lowcoder数据库操作4:显示查询数据表格
  • 加载渲染geojson数据
  • list.forEach(s -> countService.refreshArticleStatisticInfo(s.getId())); 讲解一下语法
  • Blender cycles烘焙贴图笔记
  • Linux 文件(2)
  • JavaScript 中的五种继承方式进行深入对比
  • vue3 vite 项目中自动导入图片
  • Axure疑难杂症:垂直菜单展开与收回(4大核心问题与专家级解决方案)
  • 新能源汽车充电桩管理平台如何利用智慧技术优化资源配置问题?
  • Triton介绍和各平台支持情况分析
  • Spring 代理与 Redis 分布式锁冲突:一次锁释放异常的分析与解决
  • 每日c/c++题 备战蓝桥杯(洛谷P4715 【深基16.例1】淘汰赛 题解)
  • 基于Zynq SDK的LWIP UDP组播开发实战指南
  • redis的List为什么用ziplist和quicklist
  • SCGI 服务器详解
  • 大模型(1)——基本概念
  • JVM的内存划分
  • vue3:十三、分类管理-表格--编辑、新增、详情、刷新
  • TDengine 安全部署配置建议
  • SpringBoot+ELK 搭建日志监控平台
  • Android Kotlin权限管理最佳实践
  • 【集成电路】集成电路导论知识点
  • HJ10 字符个数统计【牛客网】
  • JavaScript:PC端特效--缓动动画
  • Linux问题排查-找到偷偷写文件的进程
  • Word2Vec详解
  • 【Canvas与图标】圆角方块蓝星CSS图标
  • python打卡训练营打卡记录day30
  • 会议动态|第十五届亚太燃烧学术年会精彩探析
  • 解释:神经网络