力扣hot100:75. 颜色分类(双指针)

75.颜色分类

本题是经典的「荷兰国旗问题」,由计算机科学家 Edsger W. Dijkstra 首先提出。

75. 颜色分类

1、遍历两遍

遍历两遍,第一遍放置0的位置,第二遍放置1的位置,我们只需要维护一个当前放置位置即可。

cpp 复制代码
class Solution {
public:
    void sortColors(vector<int>& nums) {//扫描两遍,第一遍放好0的位置,第二遍放1
        int zero = 0;
        for(int i = 0; i < nums.size(); ++ i){
            if(nums[i] == 0){
                swap(nums[i], nums[zero ++]);
            }
        }
        //复用zero
        for(int j = zero; j < nums.size(); ++ j){
            if(nums[j] == 1){
                swap(nums[j], nums[zero ++]);
            }
        }
        return;
    }
};

2、遍历一遍双指针

difficult to achieve

我们维护一个0的位置,并且维护一个1的位置:

  • 确保1的位置不小于0的位置
  • 当需要放入1时,直接加在当前指向需要放置的1的位置即可。
  • 当需要放入0时,如果后面有1,这会打断1,不过,我们可以把这个1再插入1的位置即可。如果没有1直接放入

这种方法比较难写,情况有点多,实现起来比较复杂。由于时间复杂度差不多,因此推荐使用简单方法实现!

cpp 复制代码
class Solution {
public:
    void sortColors(vector<int>& nums) {//扫描两遍,第一遍放好0的位置,第二遍放1
        int zero = 0;
        int one = 0;
        for(int i = 0; i < nums.size(); ++ i){//确保one在正确位置,情况分类比较难
            if(nums[i] == 1){
                swap(nums[i], nums[one ++]);
            }else if(nums[i] == 0){
                if(zero == one){
                    swap(nums[zero ++], nums[i]);
                    one ++;
                }else{
                    if(zero < one && zero != 0){//0有数,1也有数
                        swap(nums[one ++], nums[i]);
                        nums[one - 1] = 1;
                        nums[zero ++] = 0;
                    }else{//0没数
                        if(one != i){
                            nums[zero ++] = 0;
                            swap(nums[one], nums[i]);
                            nums[one] = 1;
                        }else{
                            swap(nums[zero ++],nums[i]);
                        }
                        one++;
                    }
                }
            }
        }
        return;
    }
};

3、双指针交换2的位置

cpp 复制代码
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n = nums.size();
        int p0 = 0, p2 = n - 1;
        for (int i = 0; i <= p2; ++i) {
            while (i <= p2 && nums[i] == 2) {
                swap(nums[i], nums[p2]);
                --p2;
            }
            if (nums[i] == 0) {
                swap(nums[i], nums[p0]);
                ++p0;
            }
        }
    }
};
相关推荐
企业数字化笔记5 小时前
视频人体姿态怎么做三维可视化?2D关键点、深度局限与技术选型
人工智能·算法·音视频
?abc!6 小时前
(数组)581. 最短无序连续子数组
数据结构·算法·leetcode
小郎君6589 小时前
MPTT树复选框的半选状态:一棵百万节点树从递归到计数器,再到区间覆盖
算法
酌沧9 小时前
MemT让记忆成为模型内生能力
jvm·人工智能·算法
hold?fish:palm9 小时前
40 二叉树的直径
c++·leetcode
Shimeri9 小时前
越卷越像:我用遗传算法做了个"内卷"实验
算法·three.js·数据可视化·遗传算法·进化算法
Evand J10 小时前
【PMSM例程1】永磁同步电机(PMSM)转速与转子电角度观测算法|基于扩展卡尔曼滤波(EKF)的传感器状态估计与误差。附下载链接
算法·电机·1024程序员节·卡尔曼滤波
guo_wen_qiang10 小时前
二叉树的层序遍历-使用双端队列Deque
算法·leetcode·1024程序员节
爱读书的小胖10 小时前
LeetCode 55 跳跃游戏 C 语言解题分析
c语言·数据结构·算法·leetcode·1024程序员节
CCblandy10 小时前
前缀缓存命中率不靠引擎靠排列:本机仿真 3 轮,易变字段放开头 98.0%→0.0%
人工智能·python·算法·自然语言处理·性能优化