这道题目和分成两块的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. CSS动画:Transform中使用频繁的scale,rotate,translate动画

    动画中,skew只是transform中的一种形式的动画,我们还可以学习scale,rotate,translate.这是目前使用比较频繁的属性动作. 1.scale动画的定义:(单位数值) scal ...

  2. 那些年被我坑过的Python——不得不知(第二章)

    问题一: Python3.5.X中的数据类型有哪些? 答:包括整型.布尔型.字符串型.浮点型.复数.列表.字典.集合.元组. 细化来说: 1.整型包括短整型和长整型,不过我们不必过度操心细节,因为短整 ...

  3. asp.net mvc 强类型视图中传入List 数据到控制器

    问题来源: 在和一位技术老师聊天时,老师问我一个mvc 表单提交的问题,问道:怎样在表单提交的时候,将 带有 List 属性的对象传入控制器? 这时,我有点呆了,以前一直都好像是 单一属性的表单提交, ...

  4. ubuntu 解压rar

    Ubuntu下解压rar文件的方法 一般通过默认安装的ubuntu是不能解压rar文件的,只有在安装了rar解压工具之后,才可以解压.其实在ubuntu下安装rar解压工具是非常简单的,只需要两个步骤 ...

  5. 用STRACE解决公司真实故障一例

    这是相关分析文档.为了职业操守,已修改相关公司敏感信息~~~ ~~~~~~~~~~~~~~~~~~~~~~~~ 关于论坛每五分钟左右,会有warning.html跳转出现的原因调查 (warning. ...

  6. db2索引创建和删除

    在表trpt_jv_rpt_log_td的tim列上创建索引 create index dw_rpt.irpt_jv_rpt_log_td_tim on dw_rpt.trpt_jv_rpt_log_ ...

  7. Delphi WebService连接数据库

    1. 图如下: 个人测试  客户端 1. 2.

  8. Final对象

    常量指不能改变的量. 在Java中用final标志,声明方式和变量类似: final double PI = 3.1415927; 虽然常量名也可以用小写,但为了便于识别,通常使用大写字母表示常量. ...

  9. 阿里云ECS试用

    公司在推一个大项目,感觉阿里云挺好用的,自己搞了台小机器平时可以跑着玩,而且可以做个跳板机,平时学校里的收费网直接用跳板机就可以访问了,直接写个脚本在自己机器上跑一下: #!/usr/bin/expe ...

  10. Redis源码阅读笔记(1)——简单动态字符串sds实现原理

    首先,sds即simple dynamic string,redis实现这个的时候使用了一个技巧,并且C99将其收录为标准,即柔性数组成员(flexible array member),参考资料见这里 ...