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

Dutch national flag. Given an array of n buckets, each containing a red, white, or blue pebble, sort them by color. The allowed operations are:

  • swap(i,j): swap the pebble in bucket i with the pebble in bucket j
  • color(i)determine the color of the pebble in bucket i

The performance requirements are as follows:

  • At most n calls to color()
  • At most n calls to swap()
  • Constant extra space.

该问题在维基百科上的解释为:

The Dutch national flag problem (DNF) is a computer science programming problem proposed by Edsger Dijkstra.The flag of the Netherlands consists of three colors: red, white and blue. Given balls of these three colors arranged randomly in a line (the actual number of balls does not matter), the task is to arrange them such that all balls of the same color are together and their collective color groups are in the correct order.

本题的限制条件n calls to color()意味着每个元素最多只能访问一次,也就是要求在遍历一次所有元素的情况下完成排序。遍历结束时红色球要全部在数组的左侧,白色球全部在中间,蓝色球全部在右侧,整个数组将被分成三部分。用current记录当前需要访问的球的位置,还需要两个位置记录红-白分界处和白-蓝分界处,用lo来标记白色球的开始位置,hi来标记白色球的结束位置。lo和current起始相同,两个从数组左侧以++方式前进,hi从数组右侧以--方式前进。循环主体设计方式:【后来看到3way-quicksort,发现这个做法与3way-quicksort很像,而且后者代码更清晰简单,特在文末附了3way-quicksort的实现】

1、当current为红色时,如果lo==current,不需要交换位置,二者均前进++一步;如果不相等,意味着current 肯定大于lo,lo和current之间都为白色球,将lo和current位置处的球进行交换,lo处就变成了红色球,current处就变成了白色球,lo需要++前进一步来标志白色球的起始位置,而此时current处的球在之前已经被遍历过(左侧的球均被遍历过),current也需要++前进一步来访问下一个球

2. 当current为白色时,该球位置正确,不需要移动,current直接++前进一步

3. 当current为蓝色时,表明该球应该放置于数组右侧,此时需要和数组右侧hi处的球交换,然后hi处的球就变成了蓝色,并且该蓝色球是已经被访问过的,hi需要往右侧--前进。而此时current处交换过来的球还没有被访问过,故current位置不需要变动,留到下一次循环进行访问。

循环体在current访问完所有的球后结束,也就是current>hi时结束,因为大于hi的节点都是由current遍历交换过来的。

代码实现:

 import java.util.Arrays;
import edu.princeton.cs.algs4.StdRandom; public class DutchNationalFlag {
public static final int RED = 0;
public static final int WHITE = 1;
public static final int BLUE = 2;
private int n;
private int[] buckets;
public int callColorNum = 0;
public int callSwapNum = 0; public DutchNationalFlag(int[] buckets) {
n = buckets.length;
this.buckets = buckets;
} public void sort() {
int lo = 0;
int hi = n - 1;
int current = lo;
while (current <= hi) {
switch(color(current)){
case RED:
if (current != lo)
swap(current, lo);
current++;
lo++;
break;
case WHITE:
current++;
break;
case BLUE:
swap(hi,current);
hi--;
break;
}
}
} private void swap(int i, int j) {
callSwapNum++;
int t = buckets[i];
buckets[i] = buckets[j];
buckets[j] = t;
} private int color(int i) {
callColorNum ++;
return buckets[i];
} public static void main(String[] args) {
int n = 10;
int[] buckets = new int[n];
for (int i = 0; i < n; i++) {
buckets[i] = StdRandom.uniform(3);
}
System.out.println(Arrays.toString(buckets));
DutchNationalFlag dnf = new DutchNationalFlag(buckets);
dnf.sort();
System.out.println("after sort call color+"+dnf.callColorNum+"times, call swap="+ dnf.callSwapNum+"times");
System.out.println(Arrays.toString(buckets));
}
}

思路参考http://www.cnblogs.com/gnuhpc/archive/2012/12/21/2828166.html

3way-quicksort实现:

     public void quickSort3way(){
int lt = 0;
int gt = n - 1;
int i = 0;
while (i <= gt) {
int cc = color(i);
if(cc < WHITE) swap(lt++,i++);
else if(cc > WHITE) swap(i,gt--);
else i++;
}
}

Coursera Algorithms week2 基础排序 练习测验: Dutch national flag 荷兰国旗问题算法的更多相关文章

  1. Coursera Algorithms week2 基础排序 练习测验: Permutation

    题目原文: Given two integer arrays of size n , design a subquadratic algorithm to determine whether one ...

  2. Coursera Algorithms week2 基础排序 练习测验: Intersection of two sets

    题目原文: Given two arrays a[] and b[], each containing n distinct 2D points in the plane, design a subq ...

  3. 2-Color Dutch National Flag Problem

    2-Color Dutch National Flag Problem 问题 a[0..n-1]中包含红元素或蓝元素;重新放置使得 红元素均在蓝元素之前. 循环不变式 每一次循环,a[0...k-1] ...

  4. Coursera Algorithms week2 栈和队列 练习测验: Queue with two stacks

    题目原文: Implement a queue with two stacks so that each queue operations takes a constant amortized num ...

  5. Coursera Algorithms week4 基础标签表 练习测验:Inorder traversal with constant extra space

    题目原文: Design an algorithm to perform an inorder traversal of a binary search tree using only a const ...

  6. Coursera Algorithms week4 基础标签表 练习测验:Check if a binary tree is a BST

    题目原文: Given a binary tree where each 

  7. Coursera Algorithms week4 基础标签表 练习测验:Java autoboxing and equals

    1. Java autoboxing and equals(). Consider two double values a and b and their corresponding Double v ...

  8. Coursera Algorithms week2 栈和队列 练习测验: Stack with max

    题目原文: Stack with max. Create a data structure that efficiently supports the stack operations (push a ...

  9. Coursera Algorithms week1 查并集 练习测验:3 Successor with delete

    题目原文: Given a set of n integers S = {0,1,…,N-1}and a sequence of requests of the following form: Rem ...

随机推荐

  1. Java笔记整理列表

    整理Java相关知识点. 2018-11-20 1:Java入门学习 2:Java进阶

  2. jquery ajax中各个事件执行顺序如下

    $(function(){ setTimeout(function(){ $.ajax({ url:'/php/selectStudent.php', }); },0); $(document).aj ...

  3. 微信小程序video监测播放进度

    video组件提供的进度相关的监测只有 bindtimeupdate ,官方说明这个函数250ms触发一次,在开发者工具上基本符合,但在真机上每隔1秒触发一次.达不到我们要求的精度.对比下音频,wx. ...

  4. CAD创建一个新的图形文件

    static void linea(void) { AcDbDatabase *pDb = new AcDbDatabase(true, false); AcGePoint3d pickPoint; ...

  5. python解析邮件的时候编码问题

    import sys import base64 import os import re s1 = '"=?UTF-8?B?56mG6Zi/5rWpKOWnnOW8iyk=?=" ...

  6. python中zip( )的使用

    zip函数简单用法 x = [1, 2, 3] y = [4, 5, 6] z = [7, 8, 9] xyz = zip(x,y,z) #得到一个zip对象 xyz #打印结果为<zip ob ...

  7. 第九节:numpy之随机数组及随机排列

  8. 初识Scrapy——1—scrapy简单学习,伯乐在线实战、json数据保存

    Scrapy——1 目录 什么是Scrapy框架? Scrapy的安装 Scrapy的运行流程 Scrapy的使用 实战:伯乐在线案例(json文件保存) 什么是Scrapy框架? Scrapy是用纯 ...

  9. [luoguP3275] [SCOI2011]糖果(差分约束)

    传送门 差分约束裸题 但是坑! 有一个点是长为10W的链,需要逆序加边才能过(真是玄学) 还有各种坑爹数据 开longlong ——代码 #include <cstdio> #includ ...

  10. 种树(codevs 1768)

    题目描述 Description 为了绿化乡村,H村积极响应号召,开始种树了. H村里有n幢房屋,这些屋子的排列顺序很有特点,在一条直线上.于是方便起见,我们给它们标上1~n.树就种在房子前面的空地上 ...