颜色分类+移动零

颜色分类

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

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

注意:
不能使用代码库中的排序函数来解决这道题。

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

进阶
一个直观的解决方案是使用计数排序的两趟扫描算法。
首先,迭代计算出0、1 和 2 元素的个数,然后按照0、1、2的排序,重写当前数组。
你能想出一个仅使用常数空间的一趟扫描算法吗?


解题思路

这道题我们结合三路快排的思想来解决。首先定义两个指针zero和two,其中zero指向数组头元素的前一个位置,two指向数组尾元素的最后一个位置。然后从数组头元素开始遍历。

  1. 当数组中的元素值为1时,直接跳过进行i++
  2. 当数组中的元素值为0时,zero++,让其指向数组第一个位置,然后进行交换,让数值为0的元素从数组最前开始往后放。最后进行i++,使其遍历下一个元素
  3. 当数组中的元素值为2时,two–,让其指向数组最后一个位置,然后进行交换,让数值为2的元素从数组最后开始往前放。(注意:这里不要进行i++,因为我们不知道和2交换后当前值为0还是1,如果为0时我们还得以当前值进入循环让其交换到数组的前半部分)

代码展示

代码如下:

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int zero=-1;
        int two=nums.size();
        for(int i=0;i<two;)
        {
            if(nums[i]==1) i++;
            else if(nums[i]==0)
            {
                zero++;
                swap(nums[zero],nums[i]);
                i++;
            }
            else
            {
                two--;
                swap(nums[i],nums[two]);
            }
        }
        return;
    }
};

移动零

题目
给定一个数组 nums,编写一个函数将所有 0 移动到数组的末尾,同时保持非零元素的相对顺序。

示例:
输入: [0,1,0,3,12]
输出: [1,3,12,0,0]

说明:

  1. 必须在原数组上操作,不能拷贝额外的数组。
  2. 尽量减少操作次数。

解题思路

首先题目说了不能借用其他数组,只能在原数组上面操作。所以我们可以先遍历数组,在遍历的过程中,将不为0 的元素从第一位开始往后放。当遍历完一次数组后,我们将后面剩下的元素直接全部赋值为0,这样就相当于把0全部滞后了。


代码展示

代码如下:

class Solution {
public:
    void moveZeroes(vector<int>& nums) {
        int k=0;
        for(int i=0;i<nums.size();i++)
        {
            if(nums[i]!=0)
            {
                nums[k++]=nums[i];
            }
        }
        for(int j=k;j<nums.size();j++)
        {
            nums[j]=0;
        }
    }
};
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值