LeetCode 75. 颜色分类

Posted hlk09

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了LeetCode 75. 颜色分类相关的知识,希望对你有一定的参考价值。

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

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

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

示例:

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

进阶:

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

Partition

将列表元素分为三类:等于一的,大于一的,小于一的。可以用三路partition实现。

在介绍三路partition前,先复习一下经典的二路partition实现。如类似算法导论上的版本:

int partition(vector<int>&arr, int low, int high)
{
    int pivot = arr[low];//选第一个元素作为枢纽元
    int location = low;//location指向比pivot小的元素段的尾部
    for (int i = low + 1; i <= high; i++)//比枢纽元小的元素依次放在前半部分
        if (arr[i] <= pivot)
            swap(arr[i], arr[++location]);
    swap(arr[low], arr[location]);
    return location;

}

partition返回的下标,下标及下标左边是全部<=pivot的。如果是想要全部<pivot,可以把if中的小于等于号改为小于号。

第二种写法是双指针的,也是从数组左边取pivot:

int mypartition(vector<int>&arr, int low, int high)
{
    int pivot = arr[low];//选第一个元素作为枢纽元
    while(low < high)
    {
        while(low < high && arr[high] >= pivot)high--;
        arr[low] = arr[high];//从后面开始找到第一个小于pivot的元素,放到low位置
        while(low < high && arr[low] <= pivot)low++;
        arr[high] = arr[low];//从前面开始找到第一个大于pivot的元素,放到high位置
    }
    arr[low] = pivot;//最后枢纽元放到low的位置
    return low;
}

对这个题,三路partition如下:

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

 



以上是关于LeetCode 75. 颜色分类的主要内容,如果未能解决你的问题,请参考以下文章

LeetCode——75. 颜色分类

leetcode75 颜色分类(Medium)

leetcode-----75. 颜色分类

leetcode75之颜色分类

[LeetCode] 75. 颜色分类

LeetCode 75. 颜色分类