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

数组——双指针:75.颜色分类

题目链接

75.颜色分类

题目重构

包含0,1,2共 n 个元素的数组 nums ,原地对它们进行排序,使得相同的元素相邻,并按照0、1、2的顺序排列。

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

方法一:单指针

思路

可以对数组进行两次遍历,第一次将所有0移到数组头部,第二次将所有1移到数组头部。这样2就都在数组尾部,完成排序。

设一个ptr指针作为排好序的元素范围,由于我们要对整个元素进行排序,所以我们使用swap函数来交换元素。这里也是用到快慢指针的思想,我们用循环里的变量i作为快指针遍历数组,ptr为慢指针,当遍历到0时,便让两个指针指向的元素交换,同时让ptr自增。

当处理完所有0,此时我们有ptr个元素0已经完成排序,不需要动了,那么我们从ptr的位置开始处理元素1。同样用快慢指针来排序。最后完成排序。

代码

int ptr = 0;
for (int i = 0; i < nums.size(); ++i) {if (nums[i] == 0) {swap(nums[i], nums[ptr++]);}
}
for (int i = ptr; i < nums.size(); ++i) {if (nums[i] == 1) {swap(nums[i], nums[ptr++]);}
}

评价

  • 时间复杂度:O(n)
    • 第一个 for 循环遍历整个数组一次,执行 n 次 操作。
    • 第二个 for 循环从 ptr 开始,最多也遍历 n 次(实际上少于 n,因为 ptr ≥ 0)
    • 两个循环是顺序执行,不是嵌套,因此总时间复杂度为:O(n)+O(n)=O(n)O(n) + O(n) = O(n)O(n)+O(n)=O(n)
  • 空间复杂度 O(1):所有操作都是原地进行的,只使用了常数级别的额外空间(如临时变量 i, ptr等)。

方法二:双指针

思路

可以多用一个指针,只需要一次遍历。两个指针分别交换0和1。p0p1分别指向下一个 0 和 1 应该被放置的位置。初始均指向0。

当我们遍历数组时:

  • 遇到1时,与 nums[p1] 交换,然后右移 p1p0不动。
  • 遇到0时,与 nums[p0] 交换
    • 应当注意到,由于p0p1分别指向下一个 0 和 1 应该被放置的位置,当我们进行过1的交换时,p1会大于p0,即在p0指向的位置开始到p1 - 1的位置都是连续的1。那么这时候遇到0,我们交换可能会将1交换到尾部。
    • 因此我们需要加一个应对方法,也就是当遇到 p0 < p1 时,我们要把nums[i]nums[p1]交换。也就是说,我们进行了这样一个操作,把原本最前面的1移到了最后一个1后面。最后,由于0和1部分都往后移了,所以两个指针都自增。

代码

int n = nums.size();
int p0 = 0, p1 = 0;
for (int i = 0; i < n; ++i) {if (nums[i] == 1) {swap(nums[i], nums[p1++]);} else if (nums[i] == 0) {swap(nums[i], nums[p0]);if (p0 < p1) {swap(nums[i], nums[p1]);}++p0;++p1;}
}

评价

  • 时间复杂度:O(n),其中 n 是数组 nums 的长度。
  • 空间复杂度:O(1)

方法三:双指针升级版

思路

方法二的两个指针都是从数组头部开始,处理0时需要考虑到已处理的所有1的影响。我们可以把两个指针分置两头。即使用p0来交换0,p2交换2,p0的初始值仍然为 0,而p2的初始值为 n − 1。我们需要把所有0交换到数组头部,把所有2交换到数组尾部。

由于指针p2是从右往左走,因此,当我们从左向右遍历超过p2的位置时,就可以停止遍历了。

  • 如果找到0,与前面的方法一样,只需要与nums[p0]交换,再p0++就行
  • 如果找到2,我们把nums[i]交换到尾部,p2--,但原本的nums[p2]可能为2或者0,不能马上把遍历指针移走,否则这个2就会留在头部。我们要再判断这个新的nums[i]是否是2,是的话继续执行交换,自增循环。等到把所有的2处理完后,再处理0。

代码

int n = nums.size();
int p0 = 0, p2 = n - 1;
for (int i = 0; i < n; ++i) {while (i <= p2 && nums[i] == 2) {swap(nums[i], nums[p2]);--p2;}if (nums[i] == 0) {swap(nums[i], nums[p0]);++p0;}
}

评价

  • 时间复杂度:O(n) —— 仅一次遍历
  • 空间复杂度:O(1) —— 原地操作
http://www.dtcms.com/a/516632.html

相关文章:

  • LLD文档核心:从模块设计到落地开发
  • 雄安做网站深圳出台科技支持政策
  • 网站域名能更该吗怎样用模板建网站
  • proc文件系统入门到精通教程
  • 点积、内积与哈达玛积详解
  • 杭州模板建站2022注册公司取名
  • 政务网站建设论文西地那非片吃了多久会硬起来
  • 金融杠杆全解析:从铁矿期货保证金计算到期权盈亏分析
  • 【工具变量】绿色金融改革创新试验区DID数据集(2000-2024年)
  • Prometheus:从概述到部署
  • 32.768khz音叉式圆柱型贴片晶振CMR200T
  • ROS2创建Python与C++功能包指南以及什么是节点(ros2第一章)
  • wordpress可以建网站吗电子商务网站建设 教案
  • vr中xr射线长度调整
  • 怎样做微信挂机平台网站建设公司的网站首页
  • 【Go】P11 掌握 Go 语言函数(二):进阶玩转高阶函数、闭包与 Defer/Panic/Recover
  • 无奈!我用go写了个MySQL服务
  • 重庆网站建设业务招聘网站推广方式主要通过
  • GaussDB 数据集成方案:ETL 工具如何简化企业上云过程
  • 如何解决 pip install 安装报错 externally-managed-environment(PEP 668)问题
  • 相向双指针|两数之和II-输入有序数组|三数之和|统计和小于目标的下标对数目|最接近的三数之和|四数之和|有效三角形的个数
  • ffmpeg4.4.2 gcc 15.2.0 编译错误
  • 免费的大语言模型API接口
  • css3 学习笔记
  • 高水平的网站建设南昌做个网站多少钱
  • 宁夏建设工程质量安全监督总网站wordpress发送文章链接过期
  • Vscode 如何配置远程环境的 ssh 连接
  • 昆明参差网站开公司建网站
  • 专业点的网站制作公司建设一个公司网站需要什么条件
  • Mybatis-Spring重要组件介绍