第二周课程的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. Python 之__slots__的作用

    # 注意:__slots__ 用来限制当前类的实例属性的,如:name.age才可被使用,添加其他的属性则报错 # 不会限制继承类的属性 class Person(): __slots__ = (&q ...

  2. 基于python xlsxwriter、xlrd 生成测试报告

    import xlsxwriter,xlrd ''' 思路: 1.获取数据 2.整合数据 3.写入文件 ''' #筛选 def filt(category,table,filt_name=None,r ...

  3. LINUX-查看进程内环境变量

    ps -ef find PID cat /proc/$PID/environ | grep ENV

  4. MySQL多表连接操作

    select * from userinfo ,dapartment where userinfo.part_id = dapartment.id; --左连接: 左边全部显示 select * fr ...

  5. Vim 写 C/C++ 的配置

    .vimrc 2018/08/08 更新 基本的配置,缩进显示行号等 给每个 C/C++ 文件添加头部,显示作者,文件创建时间 F5 编译执行 C/C++源代码 Ctrl + F 利用用 astyle ...

  6. 机器学习中jupyter lab的安装方法以及使用的命令

    安装JupyterLab使用pip安装: pip install jupyterlab# 必须将用户级目录添加 到环境变量才能启动pip install --userbinPATHjupyter la ...

  7. zend studio【快捷键】

    =================================[快捷键 zend studio]========== 1.调出查找面板[ctrl+f] 2.全文检索[ctrl+h] 3.关闭当前文 ...

  8. 远程连接工具putty与mtputty

    PuTTY是一个Telnet.SSH.rlogin.纯TCP以及串行接口连接软件 官网 http://www.chiark.greenend.org.uk/~sgtatham/putty/ putty ...

  9. nginx的安装部署以及使用

    [介绍] nginx是现在互联上非常流行的高性能的 Web 和 反向代理 服务器,也是一个 IMAP/POP3/SMTP 代理服务器. 现在很多互联网应用都使用nginx来作为负载均衡的使用,再高并发 ...

  10. unigui菜单【3】

    unigui菜单TuniTreeView 根据数据库表中的内容,显示菜单的处理: function TMainForm.CreateMenu: Integer; var myMenuPoint : P ...