荷兰国旗问题 将3种数中重复数聚集 Sort Colors

142 篇文章 20 订阅
51 篇文章 0 订阅

题目源自于leetcode。好题。普通方法很好想,高效方法想半天。

题目:有一个数组,元素只有0,1,2这三种,现在要将其排序。0全放前面,2全放后面,1放中间。

要求:只遍历一趟。空间复杂度为O(1)。

思路:

    换个角度,海阔天空。起初我一直想用左右端指针做,把左端的非0换成0,把右端的非2换成2。但是到中间部位就乱了,因为左右端是同时进行的。

    看了网上的解答。方法非常精妙。还是有左右两端指针。但是多一个指针从左到右扫描。其实这个指针既充当扫描指针、又充当中间数字1序列的末尾。扫描的同时实时更新右端指针的0序列和左端指针的2序列。非常的巧妙。

    这实际上是快速排序的三路划分思想。下标left表示左路与中路的界限,下标right表示右路和中路的界限。

class Solution {
public:
    void sortColors(int A[], int n) {
        if(A == NULL || n <= 1)
            return;
        int left, right, cur;
        left = 0; //指向1序列最左侧的1
        right = n-1; //指向2序列最左侧的1的左侧的未知元素
        cur = 0; //对未知元素进行遍历
        while(cur <= right) //cur负责从左到右的遍历
        {
            if(A[cur] == 0)
            {
                swap(A[cur++], A[left++]); //A[cur]与1序列最左侧的1交换
            }
            else if(A[cur] == 1)
            {
                cur++; //啥也不干
            }
            else
            {
                swap(A[cur], A[right--]); //交换过去的那个数还未判定,不要自增
            }
        }
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值