leetcode [75. 颜色分类]

(https://leetcode-cn.com/problems/sort-colors/)

题目读完

这怎么写啊,难道除了题目说的两趟扫描还有其他的吗?(困惑脸

思考ing

完蛋,没想法,开始点提示,发现提示说的就是题目中的两趟扫描 = = ,发现了标签中的双指针

思考ing,题目说能不能写个一趟的,如果从前往后好像没什么用吧(我只知道前边的情况但后面什么情况一概不知啊)....这时候想到了双指针

题目最终的结果是左边全是0,右边全是2,中间一坨是1,可以用两个指针,一个从前往后扫,是0就跳;另一个从后往前扫,是2就跳;最终两个指针停下来有两种情况,1.一个指针是1,另一个指针是0/2 2.全是1 如果是第一种情况,那直接两个指针指向的数交换就行了,如果是第二种情况怎么办?

思考ing,如果是第二种情况那就进入了“最终决胜阶段”,可以分别记录两个1的位置,然后让i指针接着往后扫,是1就跳过,是0就与左边的1交换,是2就与右边的1交换,然后..over

/*
    关键字在于“一趟”
    怎么像变魔术一样一趟扫完,数组也排好序了?
    双指针?->两个都是1怎么办
*/
class Solution {
public:
    void sortColors(vector<int>& nums) {
        int i = 0, j = nums.size()-1,left;
        while(i < j){
            while(i < j && nums[i] == 0) i++;
            while(i < j && nums[j] == 2) j--;
            if (i >= j) break;//特判一下
            if (nums[i] == 1 && nums[j] == 1){//进入了最终决胜阶段
                left = i;
                while(i <= j){
                    while(i <= j && nums[i] == 1) i++;
                    if (i > j) break;
                    //cout<<1;
                    if (nums[i] == 0){
                        swap(nums[left],nums[i]);
                        left++;
                    }else{
                        swap(nums[j],nums[i]);
                        j--;
                    }
                }
            }else{//否则就是一个是1,另一个是0/2,就单纯的交换一下就好
                swap(nums[i],nums[j]);
            }
        }
    }
};

这个思想其实和官方题解中的第三种有点类似,这题感觉挺有意思的hhh

"没有天赋异禀,那就加倍努力"
原文地址:https://www.cnblogs.com/Beic233/p/13779770.html