荷兰国旗问题的转化

问题描述:现有红,白,蓝三个不同颜色的小球,乱序排列在一起,请重新排序这些小球,使得红白蓝三色的同颜色的球在一起这个问题之所以叫荷兰国旗,是因为我们可以将红白蓝三色小球想想成条状物,有序排列后正好组成荷兰国旗。问题转化为:给定数组A[0…N-1],元素只能取0,1,2三个值,设计算法,使得数组排列成“000…00…11…11…22…22"形式。

1.实现思路:使用三个指针,分别指向首尾和当前位置cur指向1的末尾,begin指向0的末尾,end指向2的开始,依次遍历即可。
①实现方法如下:

void holland(int* a,int size) {
	int begin = 0;
	int cur = 0;
	int end = size - 1;
	while (cur<=end)
	{
		if (a[cur]==2)
		{
			swap(a[cur], a[end]);
			end--;
		}
		else if(a[cur]==1)
		{
			cur++;
		}
		else//a[cur]=0
		{
			if (begin==cur)
			{
				begin++;
				cur++;
			}
			else
			{
				swap(a[begin], a[cur]);
				begin++;
			}
		}
	}
}

②上述代码优化
优化1(核心:当a[begin]和a[cur]交换后,a[cur])必为1,所以cur直接++:

void holland1(int* a, int size) {
	int begin = 0;
	int cur = 0;
	int end = size - 1;
	while (cur <= end)
	{
		if (a[cur] == 2)
		{
			swap(a[cur], a[end]);
			end--;
		}
		else if (a[cur] == 1)
		{
			cur++;
		}
		else//a[cur]=0
		{
			//if (begin == cur)
			//{
			//	begin++;
			//	cur++;
			//}
			//else
			//{
			//	swap(a[begin], a[cur]);
			//	//当begin! = cur时,交换过后,a[cur]=1(归纳法得出),所以可以直接cur++
			//	begin++;
			//	cur++;
			//}

			//上述注释代码的简化
			if (begin!=cur)
			{
				swap(a[begin], a[cur]);
			}
			begin++;
			cur++;
		}
	}
}

优化2:(改变cur的初始指向,从后向前)

void holland2(int a[], int size) {
	int begin = 0;
	int end = size - 1;
	int cur = end;
	while (cur>=begin)
	{
		if (a[cur]==2) {
			swap(a[cur], a[end]);
			end--;
			cur--;
		}
		else if(a[cur]==1)
		{
			cur--;
		}
		else  //a[cur]=0
		{
			swap(a[cur], a[begin]);
			begin++;
		}
	}
}

若有任何问题,欢迎读者随时批评指正,万分感谢!!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值