这道题目和分成两块的partition的扩展。比如有一堆0 1 2 数字组成的数组,要分成 00 00  11 1 1  222 2这样的顺序的。

利用lumoto版的partition能够非常好的解决,比hoare好多了。并且直接利用loop invariant,变成i j k三个指针,[low,i]=0 [i+1,j]=1, [j+1,k-1]=2, 里面假设新来2的话,直接k++,

假设是1的话,须要和a[j+1] swap, 同一时候j++, 假设0的话。须要先和a[i+1] swap i++, 然后和 a[j+1] swap j++, 因此算法例如以下:

void NertherlandFlags(int *a, int n)
{
int low=0,high=n-1;
int i=low-1,j=low-1;
for(int k=low;k<=high;k++)
{
if(a[k]==2) ;
else if(a[k]==1)
{
j++;
swap(a[j],a[k]);
}
else if(a[k]==0)
{
i++;
swap(a[i],a[k]);
j++;
swap(a[j],a[k]);
}
}
}

代码比較好写,感觉这都是一类题,

1.快排的partition。注意留一个pivot,算导是留最后一个,所以loop到high-1就停了,里面和pivot比。最后加一次swap把pivot放中间

loop invariant:  [low,i] <pivot, [i+1, j-1]>pivot, =放那边都行。exit loop时 j=high, 最后把swap跳进来

2.奇偶排序,整个区间划分为左奇右偶。和%2=0 =1比。loop 到high,

loop invariant:  [low,i] 奇, [i+1, j-1]偶, exit时 j=high+1, 包括整个区间了

3.荷兰国企问题,整个区间划分为0 1 2 (红 黄 蓝三块), loop 到high,

loop invariant:  [low,i] 0, [i+1, j] 1, [j+1, k-1]  exit时 j=high+1, 包括整个区间了

抱歉大家,这道荷兰国旗代码有bug。我才知道的。后经过分析主要是前面仅仅有2 或者0 2时,假设来了0,后面swap(a[j],a[k]) 会多交换一次使得交换回去,所以假设仅仅有0的情况。事实上不须要交换,而swap(a[j],a[k]) swap(a[j],a[k])都是子交换,因此1次两次不影响。于是统一到一起就是没有1区间的时候,也即[i+1,j]区间空,依据性质最多相差1。因此是i==j的时候出错,所以此时少一次swap, 可是i++ j++须要的 保持ij同步

事实证明未经过OJ測试的代码非常难保证正确性。leetcode setcolor题 就是上面的挂了,于是经过多种组合条件分析发现bug。单独处理1 interval空的情况

void sortColors(int a[], int n) {
int i=-1,j=-1;
for(int k=0;k<=n-1;k++)
{
if(a[k]==0)
{
if(i==j)//before are 2 or 0 2, swap one is only, two will error, also 0 swap once is ok, so that is no 1 interval would only swap once
{
i++;
swap(a[i],a[k]);
j++;
}
else
{
i++;
swap(a[i],a[k]);
j++;
swap(a[j],a[k]);
}
}
else if(a[k]==1)
{
j++;
swap(a[j],a[k]);
}
}
}

附上July版本号,前面 0 1区间 最后面2区间  1 2 之间没处理的

void sortColors(int a[], int n) {
int begin=0,end=n-1,current=0;
while(current<=end)
{
if(a[current]==0)
swap(a[begin],a[current]),begin++, current++;
else if(a[current]==1)
current++;
else if(a[current]==2)
swap(a[current],a[end]),end--; //current not move
}
}

这样的不用考虑特殊情况。比方 仅仅有2 和仅仅有0 2的区间的情况,事实上也是单向扫描过来的,仅仅是调整了未处理部分和 0 1 2 区间的顺序而已,由于指针从current+1, 到end处理了。一个

指针扫描的,还是单向扫描好。事实上也不是Hoart版啦,所以自己不用管Hoard版,坚持Lumoto版就能够了,sumous_t大神似乎也是的。

似乎另一种改进第一个版本号的思路。就是不swap,而是覆盖,像优化partition一样的

附上July博客 https://github.com/bolpigo/The-Art-Of-Programming-By-July/blob/master/ebook/zh/02.07.md

sumous_t 大神代码: https://github.com/julycoding/The-Art-Of-Programming-By-July/blob/master/ebook/code/python/2.8:%20%E8%8D%B7%E5%85%B0%E5%9B%BD%E6%97%97%E9%97%AE%E9%A2%98.py

再附上sumous_t大神帮我改动后AC的代码,膜拜下大神,还是女博士哦:)

void sortColors(int a[], int n) {
int low=0,high=n-1;
int i=low-1,j=low-1;
for(int k=low;k<=high;k++)
{
if(a[k]==2) ;
else if(a[k]==1)
{
j++;
swap(a[j],a[k]);
}
else if(a[k]==0)
{ i++;j++;swap(a[j],a[k]);swap(a[j],a[i]); }
}

July收集荷兰国旗问题之三路partition的更多相关文章

  1. 快速排序与荷兰国旗及Partition问题

    快速排序与荷兰国旗及Partition问题 需求: 1.Partition过程 给定一个数组arr,和一个整数num.请把小于等于num的数放在数组的左边,大于num的数放在数组的右边. 要求额外空间 ...

  2. 算法笔记_051:荷兰国旗问题(Java)

    目录 1 问题描述 2 解决方案   1 问题描述 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫荷兰国旗,是因为 ...

  3. 荷兰国旗问题、快排以及BFPRT算法

    荷兰国旗问题 给定一个数组arr,和一个数num,请把小于num的数放数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边.要求额外空间复杂度O(1),时间复杂度O(N). 这个问题 ...

  4. 荷兰国旗 Flag of the Kingdom of the Netherlands

    问题描述:现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫做荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列 ...

  5. ACM 荷兰国旗问题

    荷兰国旗问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:1   描述 荷兰国旗有三横条块构成,自上到下的三条块颜色依次为红.白.蓝.现有若干由红.白.蓝三种颜色的条块序列,要 ...

  6. Coursera Algorithms week2 基础排序 练习测验: Dutch national flag 荷兰国旗问题算法

    第二周课程的Elementray Sorts部分练习测验Interview Questions的第3题荷兰国旗问题很有意思.题目的原文描述如下: Dutch national flag. Given ...

  7. NYOJ_268_荷兰国旗问题

    荷兰国旗问题 时间限制:3000 ms  |  内存限制:65535 KB 难度:1 描写叙述 荷兰国旗有三横条块构成,自上到下的三条块颜色依次为红.白.蓝.现有若干由红.白.蓝三种颜色的条块序列.要 ...

  8. Java实现荷兰国旗问题

    问题描述 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列后 ...

  9. java荷兰国旗问题

    荷兰国旗包含三种颜色:红.白.蓝. 有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列.它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素.等 ...

随机推荐

  1. 16_用LVM扩展xfs文件系统(当分区空间不够时)

    1. 查看当前卷组空间(volume group)使用情况 [root@localhost ~]# vgdisplay 从下面的代码中发现剩余空间为0 --- Volume group --- VG ...

  2. JavaScript中document.cookie

    “某些 Web 站点在您的硬盘上用很小的文本文件存储了一些信息,这些文件就称为 Cookie.”—— MSIE 帮助.一般来说,Cookies 是 CGI 或类似,比 HTML 高级的文件.程序等创建 ...

  3. django访问sqlserver中的坑

    首先不用说先安装django-sqlserver    pip install django-sqlserver 然后在settings.py中修改'ENGINE': 'sqlserver_ado', ...

  4. 【转】Spring注解详解

    http://blog.csdn.net/xyh820/article/details/7303330/ 概述 注释配置相对于 XML 配置具有很多的优势: 它可以充分利用 Java 的反射机制获取类 ...

  5. MiniProfiler.3.0.10 用于MVC4.0中不能显示SQL语句

    MiniProfiler.3.0.10 用于MVC4.0中可以显示执行时间,但是不能显示SQL语句,怎么解决?

  6. ubuntu wubi安装注意事项

    从这个镜像下载 http://mirrors.163.com/ubuntu-releases/12.10/ ubuntu-12.10-desktop-amd64.iso 和 wubi.exe然后放到同 ...

  7. unix io 模型浅析

    POSIX中对同步IO和异步IO的规定: 同步IO操作:引起进程的阻塞直到IO操作完成,异步IO操作:IO操作不会引起进程阻塞 在UNIX下,有5中操作模型: 阻塞IO,非阻塞IO,IO复用,信号驱动 ...

  8. python MySQLdb segmentation fault

    import MySQLdb conn = MySQLdb.connect(host=_host,user=_user,passwd=_passwd,db=_db,charset=_charset,p ...

  9. Java工程转换为Maven工程

    1. 前言 在开发中经常要建立一个Maven的子工程,对于没有模板的同学来说从Java工程来转换也是一个不错的选择.本文就如何从一个Java工程创建一个Maven工程做了一个介绍,相信对于将一个Jav ...

  10. 7.DropDownList的绑定

    ListView中是无法像TextBox等控件那样将DropDownList的选中值绑定到数据字段的,必须编程处理.如例子:人员的性别(男,女,保密),三个值固定写在DropDownList中. 在显 ...