81 颜色分类-荷兰旗问题(Sort Colors)

1 题目

题目:颜色分类(Sort Colors)
描述:给定一个包含红,白,蓝且长度为 n 的数组,将数组元素进行分类使相同颜色的元素相邻,并按照红、白、蓝的顺序进行排序。

  1. 我们使用整数 0,1 和 2 分别代表红,白,蓝。
  2. 不能使用代码库中的排序函数来解决这个问题。
  3. 排序需要在原数组中进行。
  4. 你不可以使用计数排序(Counting Sort)来完成这道题目。

lintcode题号——148,难度——medium
该问题最早是由荷兰人Dijkstra提出的,所以该问题又叫荷兰旗问题。

样例1:

输入 : [1, 0, 1, 2]
输出 : [0, 1, 1, 2]
解释 : 原地排序。

2 解决方案

2.1 思路

  可以把数组看成左、中、右三个区间,在一开始所有的数组元素都在中间的区间,使用一个指针(游标指针)指向数组头,遍历整个数组,如果遇到红色,则将其交换到左区间中,此处需要另一个指针(左指针)来指示左区间的范围;如果遇到蓝色,则将其交换到右区间中,同样需要另一个指针(右指针)来指示右区间的范围。遍历结束后,颜色即被分类完成。

2.2 时间复杂度

  时间复杂度为O(n)。

2.3 空间复杂度

  空间复杂度为O(1)。

3 源码

细节:

  1. 游标指针index遍历序列,找到0交换至左边,找到2交换至右边,找到1跳过,不断扩大左右分区,最后中间自然剩下的全部是1。
  2. 与右边交换的时候,需要注意游标指针在交换完成后并不右移,因为从右边交换回来的数还需要重新进入循环进行判断。

C++版本:

/**
* @param nums: A list of integer which is 0, 1 or 2
* @return: nothing
*/
void sortColors(vector<int> &nums) {
    // write your code here
    if (nums.size() < 2)
    {
        return;
    }

    int left = 0;
    int right = nums.size() - 1;
    int index = 0;
    while (index <= right)
    {
        if (nums.at(index) == 0) // 命中0时,left和index都右移
        {
            swap(nums.at(left++), nums.at(index++));
            continue;
        }
        if (nums.at(index) == 1) // 命中1时,index都右移,直接跳过该数
        {
            index++;
            continue;
        }
        if (nums.at(index) == 2) // 命中2时,right都右移,index不动,交换回来的数还需要重新判断
        {
            swap(nums.at(right--), nums.at(index));
            continue;
        }
    }
}

猜你喜欢

转载自blog.csdn.net/SeeDoubleU/article/details/124642303
今日推荐