July收集荷兰国旗问题之三路partition
这道题目和分成两块的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的更多相关文章
- 快速排序与荷兰国旗及Partition问题
快速排序与荷兰国旗及Partition问题 需求: 1.Partition过程 给定一个数组arr,和一个整数num.请把小于等于num的数放在数组的左边,大于num的数放在数组的右边. 要求额外空间 ...
- 算法笔记_051:荷兰国旗问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫荷兰国旗,是因为 ...
- 荷兰国旗问题、快排以及BFPRT算法
荷兰国旗问题 给定一个数组arr,和一个数num,请把小于num的数放数组的左边,等于num的数放在数组的中间,大于num的数放在数组的右边.要求额外空间复杂度O(1),时间复杂度O(N). 这个问题 ...
- 荷兰国旗 Flag of the Kingdom of the Netherlands
问题描述:现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫做荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列 ...
- ACM 荷兰国旗问题
荷兰国旗问题 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描述 荷兰国旗有三横条块构成,自上到下的三条块颜色依次为红.白.蓝.现有若干由红.白.蓝三种颜色的条块序列,要 ...
- Coursera Algorithms week2 基础排序 练习测验: Dutch national flag 荷兰国旗问题算法
第二周课程的Elementray Sorts部分练习测验Interview Questions的第3题荷兰国旗问题很有意思.题目的原文描述如下: Dutch national flag. Given ...
- NYOJ_268_荷兰国旗问题
荷兰国旗问题 时间限制:3000 ms | 内存限制:65535 KB 难度:1 描写叙述 荷兰国旗有三横条块构成,自上到下的三条块颜色依次为红.白.蓝.现有若干由红.白.蓝三种颜色的条块序列.要 ...
- Java实现荷兰国旗问题
问题描述 现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球.白球.蓝球.这个问题之所以叫荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列后 ...
- java荷兰国旗问题
荷兰国旗包含三种颜色:红.白.蓝. 有三种颜色的球,算法的目标是将这三种球按颜色顺序正确地排列.它其实是三向切分快速排序的一种变种,在三向切分快速排序中,每次切分都将数组分成三个区间:小于切分元素.等 ...
随机推荐
- C宏系统缺陷
这两天稍稍看了一下boost的preprocessor库,发觉boost那帮疯子竟然利用各种奇技淫巧定义出各种数据类型和结构,还在上面定义出加减乘除等等各种运算,在快速浏览的过程中,还瞄到了很眼熟的各 ...
- Asp.net 实现图片缩放 无水印(方法一)
/// <summary> /// 图片缩放 无水印 /// </summary> /// <param name="sourceFile">图 ...
- C# winform DataGridView操作 (转)
C# DataGridView控件动态添加新行 DataGridView控件在实际应用中非常实用,特别需要表格显示数据时.可以静态绑定数据源,这样就自动为DataGridView控件添加相应的行.假如 ...
- Ubuntu 字体安装
命令安装: 以微软雅黑字体为例(其他的宋体.黑体等点阵字体都一样的),我们的雅黑字体文件是:Yahei.ttf(放在自己的主目录下)(在widows目录的Fonts目录下找需要的字体)由于我是双系 ...
- C#.NET Winform 通用开发框架
C/S系统开发框架-企业版 V4.0 (Enterprise Edition) 简介: http://www.csframework.com/cs-framework-4.0.htm 视频下载: 百度 ...
- linux系统删除空间后系统分区空间仍不释放问题
总结的原因: 1.删除文件文件后没有清空回收站; 2.删除的文件不在系统分区,在其他分区上; 3.删除的文件被保留在了/tmp分区下,而/tmp分区不是独立的分区,是在根分区/的基础上划分出来的分区; ...
- Python自动化运维之28、Django(二)
一.FORM 1.概述 django表单系统中,所有的表单类都作为django.forms.Form的子类创建,包括ModelForm 关于django的表单系统,主要分两种 基于django.for ...
- WSGI规格说明书
PEP 333 这应该是WSGI最权威的文档了 http://www.python.org/dev/peps/pep-3333/ 值翻译了最重要的前面部分,后面读者可以参考 当然文档有些生硬,欢迎 ...
- Unity3d 基础知识学习 工具篇
Unity3d 层(layer)的学习 @广州小龙 unity中的层是个很有用的东西, 点击层的下拉框,点击Add Layer,可以打开层管理器,我新建了一个层为test 他的id值是8,这个后面会 ...
- Vessels
Codeforces Round #218 (Div. 2) D:http://codeforces.com/problemset/problem/371/D 题意:就是有一些盘子,盘子里可以装水,这 ...