LeetCode-75.颜色分类

1.题目描述

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

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

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

示例:

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

进阶:

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

2.一般解法

从前往后遍历数组,记下数组中0,1,2出现的个数,之后对数组进行重写

void sortColors(vector<int>& nums) {
    int nRed = 0, nWhite = 0, nBlue = 0;
    for(int i=0;i<nums.size();++i)
    {
        if(nums[i] == 0)
        {
            nRed++;
        } 
        else if(nums[i] == 1)
        {
            nWhite++;
        }
        else
        {
            nBlue++;
        }
    }

    int nIndex = 0;
    for(int i=0;i<nRed;++i)
    {
        nums[nIndex] = 0;
        nIndex++;
    }
    for(int i=0;i<nWhite;++i)
    {
        nums[nIndex] = 1;
        nIndex++;
    }
    for(int i=0;i<nBlue;++i)
    {
        nums[nIndex] = 2;
        nIndex++;
    }
}

3.进阶解法

采用快速排序中三路快排的思路。n为数组的长度,通过lt、gt两个变量将数组分割成三个部分,定义如下:

nums[0...lt] nums[lt+1,gt+1] nums[gt...n-1]
=0 =1 =2

从前往后遍历数组,遍历过程中保持这个定义不变。

void sortColorsPromot(vector<int>& nums) {
    // nums[0...lt]中的元素全为0 
    // nums[gt...n-1]中的元素全为2
    // nums[lt+1...gt-1]中的元素全为1

    int i = 0, lt = -1, gt = nums.size();
    // 循环终止条件,当i追上gt时,表明排序完成
    while(i<gt)
    {
        if(nums[i] == 0)
        {
            lt++;
            swap(nums[i], nums[lt]);
            i++;
        }
        else if(nums[i] == 2)
        {
            gt--;
            swap(nums[i], nums[gt]);
        }
        else
        {
            i++;
        }
    }
}
posted @ 2019-01-27 20:24  Blue影  阅读(127)  评论(0编辑  收藏  举报