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

LeetCode刷题记录----75.颜色分类

2025/9/30

题目(Medium):

75.颜色分类


我的思路:

很显然,这里可以看成是要这个数组进行升序排序。所以我们可以用任意的排序算法来解决。这里我选择用快速排序:

public class Solution {public void SortColors(int[] nums) {Qsort(nums, 0, nums.Length-1);}private void Qsort(int[] nums, int left, int right){if(left >= right)return;int privotIndex = new Random().Next(left, right);int privot = nums[privotIndex];Swap(nums, privotIndex, right);int index = left;for(int i = left; i < right; i++){if(privot > nums[i]){Swap(nums, index, i);index++;}}Swap(nums, index, right);Qsort(nums, left, index-1);Qsort(nums, index+1, right);}private void Swap(int[] nums, int i, int j){if(i == j)  return;int temp = nums[i];nums[i] = nums[j];nums[j] = temp;}
}

时间复杂度:O(nlogn)

空间复杂度:O(n)

不过很显然,这题只有0,1,2这三个元素要排序,直接这样上排序算法有点大炮打蚊子了。应该是有更巧妙的解法的


优化思路:

1.单指针两次扫描

很显然在结果中我们可以看出,0总是排在前面,1总是排在中间,2总是排在后面。我们可以先找到数组中所有的0,让他们排在前面;之后再找到数组中所有的1,让它们排在中间。至于2,当0,1排序完了之后,就应该已经不用排了。

因此我们通过一个指针标记当前要放置0或者1的位置,来通过两次扫描(第一次扫描把0放在指针位置,指针前进;第二次扫描把1放在指针位置,指针前间)。期间每次扫描以指针的位置起始,初始的时候指针位置为0

具体代码如下:

public class Solution {public void SortColors(int[] nums) {int n = nums.Length;if(n == 1)  return;int index = 0;//第一次遍历把所有0放置在数组的头部for(int i = 0; i < n; i++){if(nums[i] == 0){Swap(nums, i, index);index++;}}//第二次遍历把所有的1放置在所有放置好0的尾部for(int i = index; i < n; i++){if(nums[i] == 1){Swap(nums, i, index);index++;}}}private void Swap(int[] nums, int left, int right){if(left == right) return;int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}
}

时间复杂度:O(N)
空间复杂度:O(1)

2.双指针首部开始

还可以把扫描次数优化到一次。此时需要用双指针,p0指向0该放置的位置,p1指向1该放置的位置。

①当扫描到0的时候,放置到p0的位置,(如果p0 == p1,p0和p1都++(因为放了0就不可能放1了))

  • 不过这里注意:如果p0 < p1,那把0交换到p0位置的时候,肯定是把原本在p0位置的1交换了出去,所以说此时要再把这个1交换到p1的位置(此时p0++,p1也++)

②当扫描到1的时候,放置到p1的位置,p1++

具体代码如下:
 

class Solution {
public:void sortColors(vector<int>& nums) {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]);++p1;} else if (nums[i] == 0) {swap(nums[i], nums[p0]);if (p0 < p1) {swap(nums[i], nums[p1]);}++p0;++p1;}}}
};

时间复杂度:O(N)

空间复杂度:O(1)

【这里用的是LeetCode官方的题解,我写的好像没保存到,我服了。不过思路差不多的】

3.双指针首尾收缩

还可以通过在两段的指针,考虑把0放置在左边,2放置在右边位置来达到最终的排序结果。

也就是:设置首尾指针left = 0 , rigth = n-1

①如果遇到0了,交换到left的位置,left++

②如果遇到2了,交换到right的位置,right--

  • 不过注意,此时交换了之后,当前位置依然有可能是2,此时应该循环执行该交换,直到right索引到达当前位置了为止。
  • 如果交换了之后,当前位置是0,那么就按①处理
  • 如果交换了之后,当前位置是1,不用处理

具体代码如下:(这个版本的代码的思考逻辑比较线性)

public class Solution {public void SortColors(int[] nums) {int n = nums.Length;if(n == 1)  return;int left = 0, right = n-1;for(int i = 0; i <= right && left < right; i++){if(nums[i] == 0){//交换到头位置Swap(nums, i, left);left++;}else if(nums[i] == 2){//交换到尾部位置Swap(nums, i, right);right--;//如果此时位置还是2的话,那就继续交换while(nums[i] == 2 && i < right){Swap(nums, i, right);right--;}//如果此时位置是0了,那就按是0时候的交换规则if(nums[i] == 0){Swap(nums, i, left);left++;}}}}private void Swap(int[] nums, int left, int right){if(left == right) return;int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}
}

时间复杂度:O(N)

空间复杂度:O(1)

下面还有一个合并了部分重复逻辑的代码0(思路一样的,只是写法表现上更精简一点了):

public class Solution {public void SortColors(int[] nums) {int n = nums.Length;if(n == 1)  return;int left = 0, right = n-1;for(int i = 0; i <= right && left < right; i++){while(nums[i] == 2 && i < right){Swap(nums, i, right);right--;}if(nums[i] == 0){Swap(nums, i, left);left++;}}}private void Swap(int[] nums, int left, int right){if(left == right) return;int temp = nums[left];nums[left] = nums[right];nums[right] = temp;}
}

总结:

①对于这种固定只有几个数的排序(3个以内),我们完全可以因为提前直到它们的位置而对单个数字所在位置进行单独的排列。因为元素少,所以在对一两个元素排序完后,剩余的元素也自动排序好了。

http://www.dtcms.com/a/430876.html

相关文章:

  • QQ可以在网站做临时会话么温州的网站建设公司
  • Java-Spring 入门指南(十七)SpringMVC--Apipostl与RestFul实战测试
  • Codeforces Round 993A Easy Problem
  • OSI模型、网络地址、与协议
  • Codeforces Round 993B. Normal Problem
  • 《嵌入式 – GD32开发实战指南(RISC-V版本)》第3章 GPIO流水灯的前世今生
  • 深圳手机网站建设哪家好表白链接生成器
  • GameObject 常见类型详解 -- 光环生成对象(AURA GENERATOR)
  • 29.CSS 3D 加载转轮 | CSS 动画效果
  • 潍坊制作网站用淘宝做公司网站
  • AMQP协议深度解析:消息队列背后的通信魔法
  • CSP-J/S复赛真实考试场景还原与备考策略
  • 攻防世界-Web-inget
  • flex布局学习记录
  • unordered_map和unordered_set的使用以及哈希表的实现
  • Powershell 管理 后台/计划 作业(六)
  • 北京网站建设公司东为企业网络营销方案策划书
  • 四川网站营销seo什么价格网站建设哪家g
  • k8s-pod的镜像升级与回滚
  • Django 从入门到进阶:构建完整的博客系统
  • XYplorer(多标签文件管理器) 多语便携版
  • 哈尔滨公告最新消息枣庄seo推广
  • 从输入网址到网页呈现:深入理解 HTTP 及其背后的网络世界
  • 建设一个网站需要什么软件抖音小程序在哪里找
  • Rust语言简介
  • 【无标题】Heartbeat高可用配置实践
  • 【LangChain】P6 对话记忆完全指南:从原理到实战(中)
  • 怎样才能把网站做好app开发制作软件
  • 石家庄网站建设外包公司工艺品网站模版
  • 【LaTeX】 5 LaTeX 文档类