75. Sort Colors

思路:

可以通过计数0,1,2的个数,然后按照个数直接个nums重新赋值覆盖原来的值即可。

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n=nums.size();
        if(n==1) return;
        int n0=0,n1=0,n2=0;
        for(auto& num:nums){
            if(num==0) n0++;
            else if(num==1) n1++;
            else n2++;
        }
        int i=0;
        while(n0>0) {
            nums[i++]=0;
            n0--;
        }
        while(n1>0){
            nums[i++]=1;
            n1--;
        }
        while(n2>0){
            nums[i++]=2;
            n2--;
        }
        return;
    }
};

单指针的方法,定义一个指针p,需要两个循环,一个循环是将0全部放在数组前面,另一个循环将1放在0后面,结束后自然2排在1后面了。
遍历nums,判断nums[i]是否为0,如果是0就将p指的元素和它交换位置,那么就能把0放到前面了,然后指针在加一。否则就i++,再继续。所以只有当0和其他数字交换的时候指针才会移动,那么指针会一直指向0应该在的位置上,所以i遍历到后面的元素0直接和指针交换即可。
对元素1同理,当0填满前面的位置后,指针就指向1应该在的位置了,同时因为0的交换,1和2都被放在0后面的位置了.

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n=nums.size();
        if(n==1) return;
        int p=0;
        for(int i=0;i<n;i++){
            if(nums[i]==0){
                swap(nums[i],nums[p]);
                p++;
            }
        }
        for(int i=p;i<n;i++){
            if(nums[i]==1){
                swap(nums[i],nums[p]);
                p++;
            }
        }
        return;
    }
};

双指针的方法就是一个循环解决0和1的位置。通过两个指针,一个p0用来和0交换,一个p1用来和1交换,当0和p0交换后 要判断p1是否大于p0,如果大于,那么就还得交换i和p1的元素,原因是i可能遇到0,然后p0指到的是1,这样交换把放在0区域的1给换出去,而此时p1大于p0说明p1不会再影响前面已经交换过的0,这时候如果i不和p1交换,那么被换出去的1就要丢失了因为i下次就要++跳过去了。然后,p0++,p1也得加,否则遇到1和p1交换后,就把前面换到的0给换出去了,也因为1是放在0后面所以也要跟着移动。如果nums[i]是1就直接和p1交换即可。
代码:

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n=nums.size();
        if(n==1) return;
        int p0=0,p1=0;
        for(int i=0;i<n;++i){
            if(nums[i]==1){
                swap(nums[i],nums[p1]);
                p1++;
            }
            else if(nums[i]==0){
                swap(nums[i],nums[p0]);
                if(p1>p0) swap(nums[i],nums[p1]);
                p0++;
                p1++;
            }
        }
        return;
    }
};

另一个是从p0和p2入手,p2从右到左遍历,那么只需要i<=p2即可。对于p2交换元素来说,可能i和p2都指向2,交换后i++会导致一个2的丢失,所以我们需要while交换i的元素直到i指向的不再为2。对于p0来说还是遇到0就和p0交换即可。

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n=nums.size();
        if(n==1) return;
        int p0=0,p2=n-1;
        for(int i=0;i<=p2;++i){
            while(i<=p2&&nums[i]==2){
                swap(nums[i],nums[p2]);
                p2--;
            }
            if(nums[i]==0){
                swap(nums[i],nums[p0]);
                p0++;
            }
        }
        return;
    }
};
posted @ 2021-04-10 14:37  Mrsdwang  阅读(47)  评论(0编辑  收藏  举报