首页 > 试题广场 >

9-9 荷兰国旗问题:设有一个仅由红、白、蓝3种颜色的条块

[问答题]
 9-9 荷兰国旗问题:设有一个仅由红、白、蓝3种颜色的条块组成的条块序列。请编写一个时间复杂度为 O(n)的算法,使得这些条块按红、白、蓝的顺序排好,即排成荷兰国旗图案。

#include <stdio.h>
#include <stdlib.h>
//只分两段的荷兰国旗问题 
void swap(int *a,int i,int j)
{
	int temp=a[i];
	a[i]=a[j];
	a[j]=temp;
}
void middle(int *a,int left,int right,int sum)
{
	int i=left-1;
	int current=left;
	int j=right;
	while(current<=right)
	{
		if(a[current]<sum)
		{
			swap(a,i+1,current);
			i++;
			current++;
		}
		else
			current++;
	}
}
//分三段的荷兰国旗问题
void three_middle(int *a,int left,int right,int number)
{
	int i=left-1;
	int current=left;
	int j=right+1;
	
	int tag;
	while(current<j)
	{
		if(a[current]<number)
		{
			swap(a,i+1,current);
			i++;
			current++;
//			printf("执行第1步\n");
//			for(tag=0;tag<=right;tag++)
//			printf("%d ",a[tag]);
//			printf("\n");
		}
		else if(a[current]==number)
		{
			current++;
//			printf("执行第2步\n");
//				for(tag=0;tag<=right;tag++)
//			printf("%d ",a[tag]);
//			printf("\n");
		}
		else
		{
			swap(a,j-1,current);
			j--;
//			printf("执行第3步\n");
//				for(tag=0;tag<=right;tag++)
//			printf("%d ",a[tag]);
//			printf("\n");
		}
		
	}
 } 
int main()
{
	int n;
	while(scanf("%d",&n)!=EOF)
	{
		int *a;
		a=(int *)malloc(sizeof(int)*n);
		int i;
		for(i=0;i<n;i++)
		scanf("%d",&a[i]);
		int k;
		scanf("%d",&k);
		three_middle(a,0,n-1,k);
			for(i=0;i<n;i++)
		printf("%d ",a[i]);
	}

	return 0;
}

分为两个问题,一个是两段,另一个是三段
编辑于 2021-01-20 11:50:43 回复(0)
/**
 *
 * 荷兰国旗问题
 *
 * 给定一个整数数组,给定一个值K,这个值在原数组中一定存在,
 * 要求把数组中小于K的元素放到数组的左边,大于K的元素放到数组的右边,
 * 等于K的元素放到数组的中间,最终返回一个整数数组,其中只有两个值,
 * 分别是等于K的数组部分的左右两个下标值。
 *
 * 例如,给定数组:[2, 3, 1, 9, 7, 6, 1, 4, 5],给定一个值4,
 * 那么经过处理原数组可能得一种情况是:[2, 3, 1, 1, 4, 9, 7, 6, 5],
 * 需要注意的是,小于4的部分不需要有序,大于4的部分也不需要有序,
 * 返回等于4部分的左右两个下标,即[4, 4]
 *
 */
public class Netherlands {


    public static void main(String[] args) {
        int[] arr = {1,6,3,5,6,7,6,9,2,4,6,8};
        Netherlands netherlands = new Netherlands();
        netherlands.netherlandsFlag(arr,0,arr.length-1,6);
    }

    /**
     *
     * @param arr
     * @param L
     * @param R
     * @param target
     */

    public int[] netherlandsFlag(int[] arr,int L,int R,int target){
        int less = L - 1;
        int more = R + 1;
        while(L < more) {
            if(arr[L] < target) {
                swap(arr, ++less, L++);
            } else if (arr[L] > target) {
                swap(arr, --more, L);
            } else {
                L++;
            }
        }
        print(arr);
        return new int[] { less + 1, more - 1 };
    }
    public  void swap(int[] arr, int i, int j) {
        int temp = arr[i];
        arr[i] = arr[j];
        arr[j] = temp;
    }


    void print(int[] arr){
        for (int i : arr) {
            System.out.print(i);
        }
    }
}



发表于 2020-09-14 13:25:52 回复(0)
public class Main{
    //for test
    public static void main(String[] args) {
        int[] arr = {1,6,3,5,6,7,6,9,2,4,6,8};
        int[] ret=netherlandsFlag(arr,0,arr.length-1);
        System.out.println(Arrays.toString(ret));
    }
    public static int[] netherlandsFlag(int[] arr,int L,int R){
        if(L>R){
            return new int[]{-1,-1};
        }
        if(L==R){
            return new int[]{L,R};
        }
        int less=L-1;
        int right=R;
        int index=L;
        while(index<R){
            if(arr[index]==arr[R]){
                index++;
            }else if(arr[index]<arr[R]){
                swap(arr,index++,++less);
            }else{
                swap(arr,index,--more);
            }
        }
        swap(arr,more,R);
        return new int[]{less+1,more};
    }
    public static void swap(int[] arr,int a,int b){
        int tmp=arr[a];
        arrr[a]=arr[b];
        arr[b]=tmp;
    }
}

发表于 2023-03-05 22:36:35 回复(0)