Dutch national flag algorithm with four colors

2019-09-22 08:45发布

问题:

I went through a solution for two and three colors but I am unable to get it for four colors.

Please help.

Will it be rrbb????yyyggg? How will we swap the green flag?

I tried the solution below but it is not working with swapping the last yellow with green.

  public class count123 {

// Java program to sort an array of 0, 1 and 2,3

    static void sort0123(int a[], int arr_size)
    {
        int lo = 0;
        int hi = arr_size - 1;
        int mid = 0,temp=0;
        int h2=arr_size - 1;
        while (mid <= hi)
        {
            switch (a[mid])
            {
            case 0:
            {
                temp = a[lo];
                a[lo] = a[mid];
                a[mid] = temp;
                lo++;
                mid++;
                break;
            }
            case 1:
                mid++;
                break;
            case 2:
            {
                temp = a[mid];
                a[mid] = a[hi];
                a[hi] = temp;

                hi--;
                h2=hi;
                break;
            }
            case 3:{
                temp = a[mid];
                a[mid] = a[h2];
                a[h2] = temp;
            //  h2--;
                //hi=h2;
                break;

            }
            }
        }
    }

    /* Utility function to print array arr[] */
    static void printArray(int arr[], int arr_size)
    {
        int i;
        for (i = 0; i < arr_size; i++)
            System.out.print(arr[i]+" ");
            System.out.println("");
    }

    /*Driver function to check for above functions*/
    public static void main (String[] args)
    {
        int arr[] = {0, 1, 0,1,2,2,0,3,3,0,0,1};
        int arr_size = arr.length;
        sort0123(arr, arr_size);
        System.out.println("Array after seggregation ");
        printArray(arr, arr_size);
    }
}
/*This code is contributed by Devesh Agrawal*/

回答1:

I run your code and realized that your code goes into infinite loop, which let does your programm do nothing.

In the main method, sort0123(arr, arr_size); is called and within this method, while (mid <= hi), mid = 6 and hi = 9 and that means 6 <= 9 and because of this resaon, this condition returns true infinitely because of the fact that it goes always to the case 3 at some point and in the case 3, the values of mid and hi are not changed.

In order to be able to run your code, you should change the value(s) of mid and/or hi logically and with it, your program can behave, how you wanted.



回答2:

The point about dutch flag aggregation is that invariants are always maintained. In a state such as 0000...11..XXX..222

  1. lo will always be at the first '1' (if it exists)
  2. mid will always be at the first unknown
  3. hi is always at the last unknown

For the 4 colour variation, assuming that you are sorting in order 0,1,3,2 as seems to be the case from the code, the rules will need to be tweaked as follows:

  1. hi is always at the last 3
  2. h2 is always at the last unknown

Following the above rules, the code will need to be changed in the following ways:

while (mid <= h2)

. . .

case 2:
        {
            temp = a[mid];
            a[mid] = a[hi];
            a[hi] = temp;

            hi--;
            h2--;
            break;
        }
case 3:{
            temp = a[mid];
            a[mid] = a[h2];
            a[h2] = temp;
            h2--;
            break;

        }

For sorting in order 0,1,2,3 simply interchange the case statements of '2' and '3'.

PS: Please make the question descriptive to help people understand the problem with ease.



回答3:

Here is my solution, written in python. The rationale behind it is to squeeze the forth color (middle right color) in between the middle left and right sub-arrays. It defines the colors as the algorithm progresses.

It has a O(n) time complexity and O(1) space complexity

from typing import List

def dutch_variant_four_colors(array: List[int]) -> List[int]:
    left = array[0]
    mid_left = None
    right = None

    left_i = 0
    mid_left_i = 0
    mid_right_i = len(array)
    right_i = len(array)

    while mid_left_i < right_i and mid_left_i < mid_right_i:
        if (array[mid_left_i] == left):
            array[mid_left_i], array[left_i] = array[left_i], array[mid_left_i]
            mid_left_i += 1
            left_i += 1
        elif (right is None or array[mid_left_i] == right):
            right_i -= 1
            mid_right_i = right_i
            array[mid_left_i], array[right_i] = array[right_i], array[mid_left_i]
            right = array[right_i]
        else:  # it is a mid value
            if (mid_left is None):
                mid_left = array[mid_left_i]
            if (array[mid_left_i] == mid_left):
                mid_left_i += 1
            else:
                mid_right_i -= 1
                array[mid_left_i], array[mid_right_i] = array[mid_right_i], array[mid_left_i]

    return array


# Sample usages
print(dutch_variant_four_colors([1,1,3,3,4,3,2,2]))
print(dutch_variant_four_colors([1,2,3,4,2,3,1,3]))
print(dutch_variant_four_colors([1,2,3,4,4]))
print(dutch_variant_four_colors([0,1,2,5,5,2,2,0]))
print(dutch_variant_four_colors([1,0,3,0,5,5]))
print(dutch_variant_four_colors([1,2,3,2,5,1,1,3]))
print(dutch_variant_four_colors([5,1,2,3,2,1,1,3]))
print(dutch_variant_four_colors([3,2,5,1]))
print(dutch_variant_four_colors([3,2,1,5]))
print(dutch_variant_four_colors([3,2,1,3,5,2,2,1,2,3,5,3,2,1,3,5,3,3,2,2,2,5,5,5,3,3,2,5,3,1,2,3,2,1,3,2,1,1,2,3,2,3,2,1,2,3,2,1,2,3,2,2,2,2,2,3,3,3,1,2,2,1,1,2,3]))

Gist available on https://gist.github.com/lopespm/81a336871ce6074f63f3cad349c3a95d