荷兰国旗算法与四种颜色

时间:2016-10-06 10:43:20

标签: java arrays sorting dutch-national-flag-problem

我经历了两种和三种颜色的解决方案,但我无法获得四种颜色。

请帮忙。

rrbb????yyyggg吗? 我们如何交换绿旗?

我尝试了下面的解决方案,但它无法使用绿色交换最后一个黄色。

  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*/

6 个答案:

答案 0 :(得分:2)

我运行你的代码并意识到你的代码进入了无限循环,这让你的程序什么都不做。

在主要方法中,sort0123(arr, arr_size);被调用,在此方法中,while (mid <= hi),mid = 6和hi = 9,这意味着6 <= 9,由于此原因,此条件返回无限真实,因为它总是在某个时刻到达案例3而在案例3中,mid和hi的值不会改变。

为了能够运行您的代码,您应该逻辑地更改mid和/或hi的值,并且使用它,您的程序可以按照您想要的方式运行。

答案 1 :(得分:1)

关于荷兰国旗聚合的观点是始终保持不变量。处于诸如0000 ... 11..XXX..222

的状态
  1. lo将始终位于第一个'1'(如果存在)
  2. mid将永远是第一个未知的
  3. 嗨总是在最后一个未知
  4. 对于4色变化,假设您按照代码0,1,3,2的顺序进行排序,则需要对规则进行如下调整:

    1. 嗨总是在最后3
    2. h2总是在最后一个未知
    3. 遵循上述规则,需要通过以下方式更改代码:

      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;
      
              }
      

      按顺序排序0,1,2,3只需交换'2'和'3'的case语句。

      PS:请将问题描述为帮助人们轻松理解问题。

答案 2 :(得分:1)

My solution in ideone

#include <iostream>
using namespace std;



void DutchNationalFlag4(int * arr , int n )
{
    int low = 0 , mid1 = 0 , mid2 = n- 1 , high = n-1 ;
    int temp;
 
    // This type of problems are best solved by using invariants 
 
    // arr[ 0 .. low -1 ] conatins 0
    // arr[ low .. mid1 -1 ] contains 1
    // arr[ mid1 .. mid2 ] is unknown
    // arr[ mid2 + 1 ... high - 1 ] contains 2
    // arr[ high .. n-1 ] contains 3
 
    // termination condition : Evert Iteration unkown length decreases so eventually will be Zero
    while( mid1 <= mid2 )
    {
        switch( arr[ mid1 ])
        {
            case 0 :
            {
                std::swap( arr[ low ] , arr [ mid1 ] );
                low ++ ;
                mid1 ++;
                break;
            }
 
            case 1 :
            {
                mid1 ++;
                break;
            }
 
            case 2 :
            {
                std::swap( arr[ mid1 ] , arr[ mid2 ]);
                mid2 -- ;
                break;
            }
 
            case 3 :
            {
                std::swap( arr[ mid1 ] , arr[ mid2 ]);
                std::swap( arr[ mid2 ] , arr[ high ]);
                mid2 --;
                high --;
                break;
            }
 
        }
    }
 
    for( int i =0 ; i < n ; i++)
    {
        cout << arr[ i ] << " " ;
    }
}
 
int main() 
{
    int arr[] = {1,2,3,0,2,1,3,0,2,1,0,1,3,1,0,2,1,0};
    int n = sizeof(arr) / sizeof(arr[0]) ;
    DutchNationalFlag4(arr , n );
    return 0;
}

我已经在上面的链接中解决了! 干杯

在问问题时,请尽量保持清楚。还要确保您的变量是直观命名的,或者您提供了适当的注释。 坦白说,我对hi和h2感到困惑,中点!

答案 3 :(得分:0)

这是我用python编写的解决方案。其背后的原理是将左右中间子数组之间的第四种颜色(中间右颜色)压缩。它随着算法的进行定义颜色。

它的时间复杂度为O(n),空间复杂度为O(1)

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]))

要约在https://gist.github.com/lopespm/81a336871ce6074f63f3cad349c3a95d上可用

答案 4 :(得分:0)

//Dutch National Flag for N different values Optimized 
//O(n) optimized solution.
//O(1) space needed where x is distinct colors (it will not change as no. of values increases)

public static void DutchNationalFlagforNvaluesOptimized(int distinctFlags, int[] flags)
        {
            int high = distinctFlags - 1, mid = distinctFlags - 2;

            int[] indexArr = new int[distinctFlags];
            for (int i = 0; i < high; i++)
            {
                indexArr[i] = 0;
            }
            indexArr[high] = flags.Length - 1;// index Array is distinct flags indexes


            for (; indexArr[mid] <= indexArr[high]; )
            {
                if (flags[indexArr[mid]] == high)
                {
                    int temp = flags[indexArr[high]];
                    flags[indexArr[high]] = flags[indexArr[mid]];
                    flags[indexArr[mid]] = temp;

                    indexArr[high]--;
                }
                else
                    if (flags[indexArr[mid]] == mid)
                    {
                        indexArr[mid]++;
                    }
                    else
                    {
                        int currentMidValue = flags[indexArr[mid]];

                        for (int i = mid; i > currentMidValue; i--)
                        {
                            int temp = flags[indexArr[i]];
                            flags[indexArr[i]] = flags[indexArr[i - 1]];
                            flags[indexArr[i - 1]] = temp;
                            indexArr[i]++;
                        }
                        indexArr[currentMidValue]++;
                    }
            }
            for (int i = 0; i < flags.Length; i++)
            {
                System.Console.Write(flags[i] + ", ");
            }
        }

答案 5 :(得分:0)

let a:string[] = ['1','2','1','0','2','4','3','0','1','3'];
    function sort3(a:string[]):void{
        let low = 0;
        let mid1 = 0;
        let mid2 = 0;
        let mid3 = 0;
        let high = a.length - 1;
        while(mid3<=high){
            switch(a[mid3]){
                case '0': [a[mid3],a[low]] = [a[low],a[mid3]];
                        low++;
                        if(mid1 < low)
                        mid1++;
                        if(mid2 < mid1)
                        mid2++;
                        if(mid3 < mid2)
                        mid3++;
                        break;

                case '1': [a[mid3],a[mid1]] = [a[mid1],a[mid3]];
                        mid1++;
                        if(mid2 < mid1)
                        mid2++;
                        if(mid3 < mid2)
                        mid3++
                        break;

                case '2': [a[mid2],a[mid3]] = [a[mid3],a[mid2]];
                            mid2++;
                            mid3++;
                       break;

                case '3':
                        mid3++;break;

                case '4': [a[mid3],a[high]] = [a[high],a[mid3]];
                            high--;
            }
        }
    }