[LeetCode] 75.颜色分类

题目

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

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

输入: [2,0,2,1,1,0]
输出: [0,0,1,1,2,2]

要求:

  • 原地算法
  • 复杂度O(n)
  • 不使用库函数

思路

充分利用只有三个元素的特性。

方法一 —— 计数填充

扫两遍,第一遍记录下来三个元素的个数,第二遍填回nums。
这样复杂度是O(2n)

方法二 —— 三指针法

使用三个指针i,j,k,分别指向0,1,2元素的末尾。

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int i=-1;
        int j=-1;
        int k=-1;
        for(int m=0;m<nums.size();m++)
        {
            if(nums[m]==0)
            {
                nums[++k]=2;
                nums[++j]=1;
                nums[++i]=0;
            }
            else if(nums[m]==1)
            {
                nums[++k]=2;
                nums[++j]=1;
            }
            else if(nums[m]==2)
            {
                nums[++k]=2;
            }
        }
    }
};

注意每个if里的顺序,当遇到0的时候,把三个指针都往前挪了一下,1会覆盖掉2 , 0会覆盖掉1。
不过这样仍然存在重复的赋值操作,还可以进一步加速。

方法三——三路快排

思路:设两个指针start,end,start指向0元素的末尾,end指向2元素的开头。因为只有三个元素,start和end中间的都是1。以1为基准,大于1的放到队末部分,小于1的放到队首部分。
代码中遇到2就把2和nums[--end]互换,把2扔到2元素的开头。这时i指针不动,指向互换过来的元素,再次比较。

遇到0的话,把0和nums[++start]互换,把0扔到0元素队尾。这时i指针+1,因为换过来的元素一定是0或1,因为i指针一直比start快,把2都换到了队末。如果是0,则i和start一定是挨着的,这样0和0互换位置没有影响;如果是1,则当前序列一定是[...0s,1,..1,0i,..]这样,互换之后,相当于把1序列中的第一个1和i互换。

遇到1的话,直接++就好。

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int start=-1;
        int end=nums.size();
        for(int i=0;i<end;)
        {
            if(nums[i]==2)
                swap(nums[--end],nums[i]);
            else if(nums[i]==1)
                i++;
            else if(nums[i]==0)
                swap(nums[++start],nums[i++]);
        }
    }
};
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值