LeetCode 75. Sort Colors

75. Sort Colors

Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.

Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.

Note:
You are not suppose to use the library’s sort function for this problem.

问题描述:
给定一个数组,数组里的每个元素代表一种颜色,红色用0表色,白色用1表示,蓝色用2表示,对数组进行一定的操作,使得数组中的0,1和2按顺序排列,即前面的都是0,然后到1,最后到2。

解题思路:
看到这个题目,一开始很容易就想到对数组中的元素进行排序不就行咯?确实进行排序后是可以得到正确的结果,但是是否有这样的必要呢?毕竟排序的复杂度不低。而且题目中已经给出了注意事项,不要用排序的方法来解决这个问题。所以,可不可以通过元素之间的交换来解决得到结果。
先从一个简单的问题开始,从左往右遍历数组nums,遍历到第i元素,假如数组的前i个元素已经符合了题目的要求,那么我们应该怎样将第i个元素插入到前面的i个元素中,使得数组前i+1个元素满足题目的要求,如下图。
这里写图片描述

可以看到,当nums[i]为0的时候,经过2个步骤的交换,就可以让前i个元素满足题目的要求,当nums[i]为1的时候,只需要经过1个步骤的交换,就可以满足要求,而且很容易想到,当nums[i]为2的时候,不需要任何的操作。这样,当我们每遍历完一个元素,都可以保证遍历过的元素都是符合题目要求的,直到遍历到最后一个元素。在使用这种方法的时候,关键点就是要记录当遍历到第i个元素的时候,前i个元素中第一个1的位置,和第一个2的位置,假如分别命名为start1和start2。

  • 当遍历到一个值为0的元素之后,经过2步交换后,需要把start1和start2都往后移动一位;
  • 当遍历到一个值为1的元素之后,经过1步交换后,需要把start2往后移动一位;
  • 当遍历到一个值为2的元素之后,不需要交换,也不需要改变start1和start2;

而因为这些start1和start2都是初始化为0,如果给出的数组中不存在1,那么start1和start2是永远都是想等的,那么就存在了一个问题,那就是遇到上图中nums[i]为1这种情况的时候,会发现经过2次交换后,数组的元素顺序是没有变化的,所以如果遇到nums[i]为1的情况,只需要执行一次的交换,因为start1和start2是一样的,所以不管是执行了第一个交换还是第二个交换,都是可行的。

代码:

#include <iostream>
#include <vector>

using namespace std;

void swap(vector<int>& nums, int x, int y) {
    int temp = nums[y];
    nums[y] = nums[x];
    nums[x] = temp;
}

void PrintNums(vector<int>& nums) {
    cout << "[ ";
    vector<int>::iterator it = nums.begin();
    for (; it != nums.end(); it++) {
        cout << *it << " ";
    }
    cout << "]" << endl;
}

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int start0 = 0, start1 = 0, start2 = 0;
        int i = 0;
        while (i < nums.size()) {
            switch (nums[i])
            {
            case 0:
                if (i >= start1) {
                    swap(nums, i, start1);
                    if (start1 != start2) swap(nums, i, start2);
                    start1++;
                    start2++;
                }
                break;
            case 1:
                if (i >= start2) {
                    swap(nums, i, start2);
                    start2++;
                }
                break;
            }
            i++;
        }
    }
};



int main(int argc, char** argv) {
    int array[] = {0, 1, 2, 1, 1};
    int count = sizeof(array) / sizeof(int);
    vector<int> nums(array, array + count);
    Solution sln;
    sln.sortColors(nums);
    PrintNums(nums);

    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值