荷兰国旗问题

时间:2014.08.07

地点:基地

----------------------------------------------------------------------------------

一、题目描写叙述

现有红白蓝三个不同颜色的小球,乱序排列在一起。又一次排列这些小球。使得红白蓝三色的同颜色的球在一起。

这个问题之即荷兰国旗问题,将红白蓝三色小球想象成条状物。有序排列后正好组成荷兰国旗。

例如以下图所看到的:


----------------------------------------------------------------------------------

二、思路

2.1方法一:排序

若是把颜色与数值相应起来。事实上是个简单的排序问题,仅仅只是元素取值仅仅含3个。且有反复,最好还是设为0 1 2 ,

于是採用各种排序都可解决。时间复杂度对于各种排序方法相应的时间复杂度。

2.2方法二:划分

将元素划分成三个部分。思路:

2.2.1 设置三个指针begin current end,begin current初始化指向数组首元素,end初始化指向数组尾元素

2.2.2 检查current指向的值,为 0 :则与begin交换值。然后current begin均后移一个位置

                                              为1 :则begin不动。current后移一个位置

                                               为2:则与end交换值。然后current后移一个位置,end前移一个位置

2.2.3反复上述过程,当current>end时停止,注意这里的条件不能够取等于(比方在序列中假设存在连续的 2 0。恰好current指向2。end指向0。则交换后为0 2,而这之前可能还有1,此时还不能终止反复过程。时间复杂符为O(n)

代码例如以下:

//荷兰国旗问题2014.08.07
#include<iostream>
#include<vector>
#include<algorithm>
void Partition(std::vector<int>& vec)
{
	auto begin = vec.begin();
	auto end = vec.end() - 1;
	auto cursor = begin;
	while (cursor <= end)
	{
		if (0 == *cursor)
		{
			std::swap(*cursor, *begin);
			++begin;
			++cursor;
		}
		else if (1 == *cursor)
			++cursor;
		else
		{
			std::swap(*cursor, *end);
			--end;
		}
	}
}
int main()
{
	std::vector<int> vec{0, 1, 1,1,2,0,2,1,0, 2, 0, 2 };
	Partition(vec);
	for (auto element : vec)
		std::cout << element << ' ';
	std::cout << std::endl;
}

这样的方法总的目标是将元素分为三部分。0放最前。所以遇到0,得和前面交换位置,遇到2得和后面交换位置,而遇到1,begin保存不动。cursor向前演进,如此可保证0在前面部分,2在后面部分,而1夹在中间。

3.统计法:

逐步检查数组,统计 0 1 2出现的次数,然后再向数组按顺序写入相应次数的值。也可到达目的。时间复杂度也是O(n)。但相比划分法多会多一个常量因子,由于这里需两次遍历数组。


转载于:https://www.cnblogs.com/lcchuguo/p/5390863.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
荷兰国旗问题是一个经典的排序问题,它要求按照荷兰国旗的颜色顺序(红、白、蓝)对一个包含红、白、蓝三种颜色的数组进行排序。 快速排序算法可以用来解决荷兰国旗问题。该算法基于分治的思想,通过多次划分和交换元素来达到排序的目的。以下是快速排序算法解决荷兰国旗问题的步骤: 1. 选择一个枢轴元素(一般是数组的最后一个元素)。 2. 初始化三个指针:low指向数组的起始位置,high指向数组的末尾位置,mid指向数组的起始位置。 3. 从头遍历数组,如果当前元素小于枢轴元素,则交换当前元素和mid指针指向的元素,并将mid指针后移一位。 4. 如果当前元素等于枢轴元素,则将high指针前移一位。 5. 如果当前元素大于枢轴元素,则交换当前元素和high指针指向的元素,并将high指针前移一位。 6. 重复步骤3到步骤5,直到low指针和high指针相遇为止。 7. 最后,将枢轴元素放在mid指针的位置上,这样数组就被分成了三个部分:小于枢轴元素的部分、等于枢轴元素的部分和大于枢轴元素的部分。 8. 递归地对小于和大于枢轴元素的部分进行排序。 以下是一个示例荷兰国旗问题的快速排序的实现(使用Python语言): ```python def dutch_flag_sort(arr): def swap(arr, i, j): arr[i], arr[j] = arr[j], arr[i] def quicksort(arr, low, high): if low < high: pivot = arr[high] mid = low for i in range(low, high): if arr[i] < pivot: swap(arr, i, mid) mid += 1 swap(arr, mid, high) quicksort(arr, low, mid - 1) quicksort(arr, mid + 1, high) quicksort(arr, 0, len(arr) - 1) return arr # 示例用法 arr = [2, 0, 2, 1, 1, 0] sorted_arr = dutch_flag_sort(arr) print(sorted_arr) ``` 上述示例代码会输出 `[0, 0, 1, 1, 2, 2]`,即按照荷兰国旗顺序排序的结果。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值