leetcode 75 颜色分类(荷兰国旗问题 双指针)
链接:https://leetcode-cn.com/problems/sort-colors/
题目
给定一个包含红色、白色和蓝色,一共 n 个元素的数组,原地对它们进行排序,使得相同颜色的元素相邻,并按照红色、白色、蓝色顺序排列。
此题中,我们使用整数 0、 1 和 2 分别表示红色、白色和蓝色。
用例
示例 1:
输入:nums = [2,0,2,1,1,0]
输出:[0,0,1,1,2,2]
示例 2:
输入:nums = [2,0,1]
输出:[0,1,2]
示例 3:
输入:nums = [0]
输出:[0]
示例 4:
输入:nums = [1]
输出:[1]
提示:
n == nums.length
1 <= n <= 300
nums[i] 为 0、1 或 2
思路
这道题学长在百度终面的时候被问到,当时他只想到了使用排序做
1. 排序
排序非常简单,直接调用sort()或者手写快排即可
  class Solution {
public:
    void sortColors(vector<int>& nums) {
        sort(nums.begin(),nums.end());
    }
};
2. 单指针 
单指针非常简单,就是遍历两次,第一次把0都放到数组最左边,第二次把1都放在数组中间
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n = nums.size();
        int ptr = 0;
        for (int i = 0; i < n; ++i) {
            if (nums[i] == 0) {
                swap(nums[i], nums[ptr]);
                ++ptr;
            }
        }
        for (int i = ptr; i < n; ++i) {
            if (nums[i] == 1) {
                swap(nums[i], nums[ptr]);
                ++ptr;
            }
        }
    }
};
3. 双指针(判断0,1)
我实现的方式比较笨 就是判断交换数是否1或0并与对应指针指向的位置做交换
其中注意p0 p1相等时 nums[i]=0时需要同时向后移动p0和p1指针
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int p0=0,p1=0;
        for(int i=0;i<nums.size();i++)
        {
            if(nums[i]==0)
            {
                swap(nums[i],nums[p0]);
                if(p0==p1)
                {
                    p0++;
                    p1++;
                }else
                    p0++;
            }
            if(nums[i]==1)
            {
                swap(nums[p1],nums[i]);
                p1++;
            }
        }
    }
};
官方题解很精妙 先判断1再判断0
如果为0时 判断前面序列是否有1 即p0 < p1条件 不重合说明有1
在进行0交换后还需对1进行交换
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int n = nums.size();
        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 (p0 < p1) {
                    swap(nums[i], nums[p1]);
                }
                ++p0;
                ++p1;
            }
        }
    }
};
4. 双指针(判断0 和2)
设置2个指针 一个指向末尾 一个指向头部
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int front =0,back=nums.size()-1;
        int i=0;
        for(int i=0;i<=back;i++)
        {
            while(i<=back&&nums[back]==2)//尾部指针如果是2的交换会失效所以必须保证指向不是2
            {
                back--;
            }
            if(nums[i]==2&&i<=back)
            {
                swap(nums[i],nums[back]);
                back--;
            }
            if(nums[i]==0&&i<=back)
            {
                swap(nums[i],nums[front]);
                front++;
            }
        }
    }
};
或者可以增加循环
只要index<=p2 情况下就继续循环
在==0或者 ==1的情况下index++
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int index=0,p0=0,p2=nums.size()-1;
        while(index<=p2)
        {
            if(nums[index]==0)
            {
                swap(nums[index],nums[p0]);
                p0++;
                index++;
            }else if(nums[index]==1)
            {
                index++;
            }else
            {
                swap(nums[p2],nums[index]);
                p2--;
            }
        }
    }
};
 
                    
                
 
                
            
         
         浙公网安备 33010602011771号
浙公网安备 33010602011771号