荷兰国旗

题目描述

拿破仑席卷欧洲大陆之后,代表自由,平等,博爱的竖色三色旗也风靡一时。荷兰国旗就是一面三色旗(只不过是横向的),自上而下为红白蓝三色。

该问题本身是关于三色球排序和分类的,由荷兰科学家Dijkstra提出。由于问题中的三色小球有序排列后正好分为三类,Dijkstra就想象成他母国的国旗,于是问题也就被命名为荷兰旗问题(Dutch National Flag Problem)。

下面是问题的正规描述: 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右,依次是一些红球、一些白球、一些蓝球。

分析与解法

初看此题,我们貌似除了暴力解决并无好的办法,但联想到我们所熟知的快速排序算法呢?

我们知道,快速排序依托于一个partition分治过程,在每一趟排序的过程中,选取的主元都会把整个数组排列成一大一小的部分,那我们是否可以借鉴partition过程设定三个指针完成重新排列,使得所有球排列成三个不同颜色的球呢?

解法一

通过前面的分析得知,这个问题类似快排中partition过程,只是需要用到三个指针:一个前指针begin,一个中指针current,一个后指针end,current指针遍历整个数组序列,当

  1. current指针所指元素为0时,与begin指针所指的元素交换,而后current++,begin++ ;
  2. current指针所指元素为1时,不做任何交换(即球不动),而后current++ ;
  3. current指针所指元素为2时,与end指针所指的元素交换,而后,current指针不动,end-- 。

为什么上述第3点中,current指针所指元素为2时,与end指针所指元素交换之后,current指针不能动呢?因为第三步中current指针所指元素与end指针所指元素交换之前,如果end指针之前指的元素是0,那么与current指针所指元素交换之后,current指针此刻所指的元素是0,此时,current指针能动么?不能动,因为如上述第1点所述,如果current指针所指的元素是0,还得与begin指针所指的元素交换。

ok,说这么多,你可能不甚明了,直接引用下gnuhpc的图,就一目了然了:

 

参考代码如下:

while( current<=end )
{
  if( array[current] ==0 )
   {
      swap(array[current],array[begin]);
      current++;
      begin++;
   }
   else if( array[current] == 1 )
   {
      current++;
   }   

   else //When array[current] =2
   {
      swap(array[current],array[end]);
      end--;
   }
}  
时间: 2024-12-06 22:17:58

荷兰国旗的相关文章

荷兰国旗问题

荷兰国旗问题: 现有红,白,蓝三个不同颜色的小球,乱序排列在一起,重新排列这些小球,使得红白蓝三色的同颜色的球在一起. 问题分析: 问题转换为:给定数组A[0,1,...,N-1],元素只能取0,1,2三个值,设计算法使得数组重新排列成“000...111..222”的形式. 可以使用三个游标,begin=0,cur=0,end=N-1. 程序实现: 1 /*************************************** 2 FileName HollandFlag.cpp 3 A

荷兰国旗问题 划分成3部分 leecode

1 public class Solution { 2 public void sortColors(int[] A) { 3 int len=A.length; 4 int beg=0; 5 int end=len-1; 6 int cur=0; 7 while(cur<=end){ 8 if(A[cur]==0) 9 { 10 swap(A,cur,beg); 11 beg++; 12 cur++; 13 14 15 } 16 else if(A[cur]==1) 17 { 18 cur++

快速排序深入之荷兰国旗问题

一.序言 在使用partition-exchange排序算法时,如快速排序算法(即使选择了一个好的关键元素pivot values),我们往往面临一个很尴尬的境地--当排序对象中有很多重复的元素,partition-exchange排序算法表现很不尽如人意.当所有元素都相等时,这就特别容易理解了.在每次递归中,左边部分是空的(没有元素比关键元素小),而右边部分只能一个一个递减移动.结果导致耗费了二次方时间来排序相等元素.为了解决这个问题(有时叫做荷兰国旗问题),我们详细介绍下解决这个问题的方法.

NYOJ_268_荷兰国旗问题

荷兰国旗问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:1 描写叙述 荷兰国旗有三横条块构成,自上到下的三条块颜色依次为红.白.蓝.现有若干由红.白.蓝三种颜色的条块序列.要将它们又一次排列使全部同样颜色的条块在一起.本问题要求将全部红色的条块放最左边.全部白色的条块放中间.全部蓝色的条块放最右边. 输入 第1行是一个正整数n(n<100),表示有n组測试数据.接下来有n行,每行有若干个由R,W,B三种字符构成的字符串序列,当中R,W和B分别表示红.白.蓝三种颜色的条块

荷兰国旗问题:

何谓荷兰国旗: 现有红.白.蓝三个不同颜色的小球,乱序排列在一起,请重新排列这些小球,使得红白蓝三色的同颜色的球在一起.这个问题之所以叫荷兰国旗,是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗. 问题转换为:给定数组A[0…N-1],元素只能取0.1.2三个值,设计算法,使得数组排列成“00…0011…1122…22”的形式. 借鉴快速排序中partition的过程.定义三个指针:begin=0.current=0.end=N-1: A[cur]==2,则A[cur] 与

[算法系列之十一]荷兰国旗问题

[问题] 现有红白蓝三个不同颜色的小球,乱序排列在一起,请重新排列这些小球,使得红白蓝三色的同颜色的球在一起.这个问题之所以叫荷兰国旗问题,是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗. [分析] 这个问题我们可以将这个问题视为一个数组排序问题.红白蓝分别对应数字0.1.2.红.白.蓝三色小球数量并不一定相同. [思路一] First, iterate the array counting number of 0's, 1's, and 2's, then overwr

荷兰国旗 Flag of the Kingdom of the Netherlands

问题描述:现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫做荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列后正好组成荷兰国旗. 解题方法1:蛮力求解 解题方法2:为了讨论方便用数字0表示红色球,用数字1表示白色球,用数字2表示蓝色球,所以最后的排序就是0...1...2... 快速排序基于划分过程,选取主元间整个数组划分为两个子数组.是否可以借鉴划分过程设定三个指针完成一次遍历完成重新排列,使得所有的球

编程之法:面试和算法心得(荷兰国旗)

内容全部来自编程之法:面试和算法心得一书,实现是自己写的使用的是java 题目描述 拿破仑席卷欧洲大陆之后,代表自由,平等,博爱的竖色三色旗也风靡一时.荷兰国旗就是一面三色旗(只不过是横向的),自上而下为红白蓝三色. 该问题本身是关于三色球排序和分类的,由荷兰科学家Dijkstra提出.由于问题中的三色小球有序排列后正好分为三类,Dijkstra就想象成他母国的国旗,于是问题也就被命名为荷兰旗问题(Dutch National Flag Problem). 下面是问题的正规描述: 现有n个红白蓝

八大基本排序---快速排序(荷兰国旗问题)

引言: 解答: 需要准备3个下标 如果当前数字=num,cur跳下一个 如果数组中的当前数字<num,把这个数(3)和小于区域的下一个数(5)交换 然后小于区域扩一下 然后cur跳下一个位置 数组中的当前数字<num,把这个数(2)和小于区域的下一个数(5)交换, 然后小于区域扩一下 然后cur跳下一个位置 PS: 如果一上来遇到的就是cur<num 把这个数(3)和小于等于区域的下一个数(3)交换[自己和自己交换] 数组中的当前数字>num,把这个数(7)和大于区域的前一个数(x