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

本文主要是介绍Coursera Algorithms week2 基础排序 练习测验: Dutch national flag 荷兰国旗问题算法,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

第二周课程的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遍历交换过来的。

 

 

 

代码实现:

 1 import java.util.Arrays;
 2 import edu.princeton.cs.algs4.StdRandom;
 3 
 4 public class DutchNationalFlag {
 5     public static final int RED = 0;
 6     public static final int WHITE = 1;
 7     public static final int BLUE = 2;
 8     private int n;
 9     private int[] buckets;
10     public int callColorNum = 0;
11     public int callSwapNum = 0;
12 
13     public DutchNationalFlag(int[] buckets) {
14         n = buckets.length;
15         this.buckets = buckets;
16     }
17 
18     public void sort() {
19         int lo = 0;
20         int hi = n - 1;
21         int current = lo;
22         while (current <= hi) {
23             switch(color(current)){
24             case RED:
25                 if (current != lo) 
26                     swap(current, lo);
27                 current++;
28                 lo++;
29                 break;
30             case WHITE:
31                 current++;
32                 break;
33             case BLUE:
34                 swap(hi,current);
35                 hi--;
36                 break;
37             }
38         }
39     }
40 
41     private void swap(int i, int j) {
42         callSwapNum++;
43         int t = buckets[i];
44         buckets[i] = buckets[j];
45         buckets[j] = t;
46     }
47 
48     private int color(int i) {
49         callColorNum ++;
50         return buckets[i];
51     }
52 
53     public static void main(String[] args) {
54         int n = 10;
55         int[] buckets = new int[n];
56         for (int i = 0; i < n; i++) {
57             buckets[i] = StdRandom.uniform(3);
58         }
59         System.out.println(Arrays.toString(buckets));
60         DutchNationalFlag dnf = new DutchNationalFlag(buckets);
61         dnf.sort();
62         System.out.println("after sort call color+"+dnf.callColorNum+"times, call swap="+ dnf.callSwapNum+"times");
63         System.out.println(Arrays.toString(buckets));
64     }
65 }

 

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

 

3way-quicksort实现:

 1     public void quickSort3way(){
 2         int lt = 0;
 3         int gt = n - 1;
 4         int i = 0;
 5         while (i <= gt) {
 6             int cc = color(i);
 7             if(cc < WHITE) swap(lt++,i++);
 8             else if(cc > WHITE) swap(i,gt--);
 9             else i++;
10         }
11     }

 

转载于:https://www.cnblogs.com/evasean/p/7217623.html

这篇关于Coursera Algorithms week2 基础排序 练习测验: Dutch national flag 荷兰国旗问题算法的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!



http://www.chinasem.cn/article/647246

相关文章

Java 线程安全与 volatile与单例模式问题及解决方案

《Java线程安全与volatile与单例模式问题及解决方案》文章主要讲解线程安全问题的五个成因(调度随机、变量修改、非原子操作、内存可见性、指令重排序)及解决方案,强调使用volatile关键字... 目录什么是线程安全线程安全问题的产生与解决方案线程的调度是随机的多个线程对同一个变量进行修改线程的修改操

Java中的雪花算法Snowflake解析与实践技巧

《Java中的雪花算法Snowflake解析与实践技巧》本文解析了雪花算法的原理、Java实现及生产实践,涵盖ID结构、位运算技巧、时钟回拨处理、WorkerId分配等关键点,并探讨了百度UidGen... 目录一、雪花算法核心原理1.1 算法起源1.2 ID结构详解1.3 核心特性二、Java实现解析2.

Redis出现中文乱码的问题及解决

《Redis出现中文乱码的问题及解决》:本文主要介绍Redis出现中文乱码的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录1. 问题的产生2China编程. 问题的解决redihttp://www.chinasem.cns数据进制问题的解决中文乱码问题解决总结

全面解析MySQL索引长度限制问题与解决方案

《全面解析MySQL索引长度限制问题与解决方案》MySQL对索引长度设限是为了保持高效的数据检索性能,这个限制不是MySQL的缺陷,而是数据库设计中的权衡结果,下面我们就来看看如何解决这一问题吧... 目录引言:为什么会有索引键长度问题?一、问题根源深度解析mysql索引长度限制原理实际场景示例二、五大解决

Springboot如何正确使用AOP问题

《Springboot如何正确使用AOP问题》:本文主要介绍Springboot如何正确使用AOP问题,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝赐教... 目录​一、AOP概念二、切点表达式​execution表达式案例三、AOP通知四、springboot中使用AOP导出

Python中Tensorflow无法调用GPU问题的解决方法

《Python中Tensorflow无法调用GPU问题的解决方法》文章详解如何解决TensorFlow在Windows无法识别GPU的问题,需降级至2.10版本,安装匹配CUDA11.2和cuDNN... 当用以下代码查看GPU数量时,gpuspython返回的是一个空列表,说明tensorflow没有找到

解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题

《解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘问题》:本文主要介绍解决未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4... 目录未解析的依赖项:‘net.sf.json-lib:json-lib:jar:2.4‘打开pom.XM

IDEA Maven提示:未解析的依赖项的问题及解决

《IDEAMaven提示:未解析的依赖项的问题及解决》:本文主要介绍IDEAMaven提示:未解析的依赖项的问题及解决,具有很好的参考价值,希望对大家有所帮助,如有错误或未考虑完全的地方,望不吝... 目录IDEA Maven提示:未解析的依编程赖项例如总结IDEA Maven提示:未解析的依赖项例如

一文详解Java Stream的sorted自定义排序

《一文详解JavaStream的sorted自定义排序》Javastream中的sorted方法是用于对流中的元素进行排序的方法,它可以接受一个comparator参数,用于指定排序规则,sorte... 目录一、sorted 操作的基础原理二、自定义排序的实现方式1. Comparator 接口的 Lam

Redis分片集群、数据读写规则问题小结

《Redis分片集群、数据读写规则问题小结》本文介绍了Redis分片集群的原理,通过数据分片和哈希槽机制解决单机内存限制与写瓶颈问题,实现分布式存储和高并发处理,但存在通信开销大、维护复杂及对事务支持... 目录一、分片集群解android决的问题二、分片集群图解 分片集群特征如何解决的上述问题?(与哨兵模