75. Two methods of color classification, 2+1 pointer and three pointer, analysis of algorithm principle

75. Color Classification

Given an array of n elements containing red, white, and blue, sort them in place so that the elements of the same color are adjacent and arranged in the order of red, white, and blue.

In this question, we use integers 0, 1, and 2 to represent red, white, and blue, respectively.

Note:
You cannot use the sorting function in the code base to solve this problem.

Example:

Input: [2,0,2,1,1,0]
Output: [0,0,1,1,2,2]
Advanced:

An intuitive solution is to use a two-pass scanning algorithm for counting and sorting.
First, iteratively calculate the number of elements 0, 1, and 2, and then rewrite the current array according to the order of 0, 1, and 2.
Can you think of a one-pass scanning algorithm that uses only constant space?

Solution 1: Double pointer first, introduce third pointer when not moving

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int len = nums.size();
        if (len < 2)
            return;
        
        int left = 0, right = len-1;
        while (left < right) {
            if (nums[left] == 0) {                              //先两边符合条件的数值
                ++left;
                continue;
            } else if (nums[right] == 2) {
                --right;
                continue;
            }

            if (nums[left] == 2) {
                swap(nums[left], nums[right]);
                --right;
            } else if (nums[right] == 0) {
                swap(nums[left], nums[right]);
                ++left;
            } else if (nums[left] == 1 && nums[right] == 1) {  //双指针寸步难行
                int mid = left+1;                              //引入第三指针
                while (mid < right && nums[mid] == 1)          //找中间不符合条件的数值
                    ++mid;
                if (mid == right)
                    return;

                if (nums[mid] == 0) {
                    swap(nums[left], nums[mid]);
                    ++left;
                } else {
                    swap(nums[right], nums[mid]);
                    --right;
                }
            }
        }
    }
};

          The idea of this method is relatively simple, and the value is relatively stable . The last 2 is always on the last side and will not be exchanged. And only when necessary (the boundary of the interval is 1 o'clock) introduce the third auxiliary pointer, without maintaining the three pointers all the time, the operation is relatively simple, and the thinking is relatively clear.

          When there are 1 on the right and many 1s on the left, with a little 0/2 in between, the algorithm will frequently introduce the third pointer, and the third pointer will repeatedly traverse from the left boundary 1 to the right.

Solution 2: Direct three pointers

class Solution {
public:
    void sortColors(vector<int>& nums) {
        int len = nums.size();
        if (len < 2)
            return;
        
        int left = 0, cur = 0, right = len-1;
        while (cur <= right) {                    //需要同步跟新left, 所以有等号
            if (nums[cur] == 0) {
                if (left != cur)
                    swap(nums[left], nums[cur]);
                ++left;
                ++cur;                            //从前往后,一步为0可以往下走
            } else if (nums[cur] == 2) {
                if (right != cur)
                    swap(nums[right], nums[cur]);
                --right;
                //++cur;                          //cur不能往前走,从后换到当前的值不知道是0/1/2
            } else {
                ++cur;                            //当cur指的数为1时,会落下left指向第一个为1的数
            }
        }
    }
};

          This solution always maintains three pointers, and the algorithm has no stability. Even if the value at the end meets the conditions, it will be changed to cur, and then the 2 encountered at the beginning is changed to the end. The stability of the value is equivalent to an order inversion.

          The algorithm is worst when the original array has 2 at the beginning and the last 2 is roughly in order.

Guess you like

Origin blog.csdn.net/sy_123a/article/details/109124139