算法笔记_051:荷兰国旗问题(Java)
目录
1 问题描述
现有n个红白蓝三种不同颜色的小球,乱序排列在一起,请通过两两交换任意两个球,使得从左至右的球依次为红球、白球、蓝球。这个问题之所以叫荷兰国旗,是因为将红白蓝三色的小球弄成条状物,并有序排列后正好组成荷兰国旗。
2 解决方案
为了方便编码与讨论,用数字0表示红球,数字1表示白球,数字2表示蓝球,所以最后生成的排列为0,1,2。
解决该问题,只需先设定三个用于指定元素的下标指针(PS:在Java中没有指针,此处方便描述):一个前指针begin,一个中指针current,一个后指针end。Current指针遍历整个数组序列:
(1)当current指针所指元素为0时,与begin指针所指的元素交换,而后current++,begin++;
(2)当current指针所指元素为1时,不做任何交换,而后current++;
(3)当current指针所指元素为2时,与end指针所指的元素交换,而后current指针不动,end--.
那么,为什么在上述第(3)步中,current指针不动?因为如果end所指元素为0时,此时current指针就不能动。
具体代码如下:
package com.liuzhen.array_2; public class HollandFlagProblem {
//输出荷兰国旗问题后的排序结果,时间复杂度为O(n),空间复杂度为O(1)
public void getHollandSort(int[] A){
int begin = 0;
int current = 0;
int end = A.length - 1;
while(current <= end){
//值得注意的是:此处if语句是使用if-else if-else if,而没有使用if-if-if。这样使用保证每一次循环只执行一个条件,
//否则,若使用if-if-if,可能会形成一次循环执行两到三个if条件,造成最终结果错误(PS:即在循环结束前,发生current > end)
if(A[current] == 0){
swap(A,begin,current);
begin++;
current++;
}
else if(A[current] == 1)
current++;
else if(A[current] == 2){
swap(A,current,end);
end--;
}
} //输出排完序后的数组A相应元素
System.out.println("对数组A进行划分后的元素顺序为:");
for(int i = 0;i < A.length;i++)
System.out.print(A[i]+" ");
} //交换数组A中m位置和n位置上元素的值
public void swap(int[] A,int m,int n){
int temp = A[m];
A[m] = A[n];
A[n] = temp;
} public static void main(String[] args){
HollandFlagProblem test = new HollandFlagProblem();
int[] A = {2,0,2,0,0,2,1,1,0,2,1,0,1,2,0,1,2,0,1,0,2,1,0,2,0,1,2,0,1,2,0,2,1,0};
test.getHollandSort(A);
}
}
运行结果:
对数组A进行划分后的元素顺序为:
0 0 0 0 0 0 0 0 0 0 0 0 0 1 1 1 1 1 1 1 1 1 1 2 2 2 2 2 2 2 2 2 2 2
参考资料:
1.《编程之法面试和算法心得》 July 著
算法笔记_051:荷兰国旗问题(Java)的更多相关文章
- 算法笔记_023:拓扑排序(Java)
目录 1 问题描述 2 解决方案 2.1 基于减治法实现 2.2 基于深度优先查找实现 1 问题描述 给定一个有向图,求取此图的拓扑排序序列. 那么,何为拓扑排序? 定义:将有向图中的顶点以线性方式进 ...
- 算法笔记_228:信用卡号校验(Java)
目录 1 问题描述 2 解决方案 1 问题描述 当你输入信用卡号码的时候,有没有担心输错了而造成损失呢?其实可以不必这么担心,因为并不是一个随便的信用卡号码都是合法的,它必须通过Luhn算法来验证 ...
- 算法笔记_138:稳定婚姻问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 何为稳定婚姻问题? 有一个男士的集合Y = {m1,m2,m3...,mn}和一个女士的计划X = {n1,n2,n3,...,nn}.每一个男士有 ...
- 算法笔记_137:二分图的最大匹配(Java)
目录 1 问题描述 2 解决方案 1 问题描述 何为二分图的最大匹配问题? 引用自百度百科: 首先得说明一下何为匹配: 给定一个二分图G,在G的一个子图M中,M的边集{E}中的任意两条边都不依附于 ...
- 算法笔记_132:最大流量问题(Java)
目录 1 问题描述 2 解决方案 1 问题描述 何为最大流量问题? 给定一个有向图,并为每一个顶点设定编号为0~n,现在求取从顶点0(PS:也可以称为源点)到顶点n(PS:也可以称为汇点)后,顶点 ...
- 算法笔记_040:二进制幂(Java)
目录 1 问题描述 2 解决方案 2.1 从左至右二进制幂 2.2 从右至左二进制幂 1 问题描述 使用n的二进制表示,计算a的n次方. 2 解决方案 2.1 从左至右二进制幂 此方法计算a的n次 ...
- 算法笔记_014:合并排序(Java)
1 问题描述 给定一组数据,使用合并排序得到这组数据的非降序排列. 2 解决方案 2.1 合并排序原理简介 引用自百度百科: 合并排序是建立在归并操作上的一种有效的排序算法.该算法是采用分治法(Div ...
- 算法笔记_233:二阶魔方旋转(Java)
目录 1 问题描述 2 解决方案 1 问题描述 魔方可以对它的6个面自由旋转. 我们来操作一个2阶魔方(如图1所示): 为了描述方便,我们为它建立了坐标系. 各个面的初始状态如下:x轴正向:绿x轴 ...
- 算法笔记_227:填写乘法算式(Java)
目录 1 问题描述 2 解决方案 1 问题描述 观察下面的算式: * * × * * = * * * 它表示:两个两位数字相乘,结果是3位数.其中的星号(*)代表任意的数字,可以相同,也可以不同, ...
随机推荐
- Eclipse generate javadoc
注:若遇到导出文档乱码,则点击上图的[next]按钮,在vm options的输入框输入 -J-Xmx180m —- 设置内存大小 (若遇到内存溢出时) -encoding utf-8 ...
- Poj1733 Parity Game(带权并查集)
题面 Poj 题解 反正只要你判断是否满足区间的奇偶性,假设每一位要么是\(1\)要么是\(0\)好了. 假设有\(S\)的前缀和为\(sum[]\),则有: 若\(S[l...r]\)中有奇数个\( ...
- 抽丝剥茧:理解Android权限机制
前一段时间面试官问我Android在Linux的基础上,权限做了哪些改变.霹雳呱啦说了一堆,但是说着说着,始终感觉自己说的缺了点东西,自己理解还是不够到位,而且网上的很多文章在原理上基本都是大同小异, ...
- IN 运算符
在前面已经介绍了IN运算符的简单使用,使用IN运算符可以用来匹配一个固定集合中的某一项.比如下面的SQL语句检索在2001.2003和2005年出版的所有图书: SELECT * FROM T_Boo ...
- [BZOJ2286][SDOI2011]消耗战(虚树DP)
2286: [Sdoi2011]消耗战 Time Limit: 20 Sec Memory Limit: 512 MBSubmit: 4998 Solved: 1867[Submit][Statu ...
- fastjson生成json时Null属性不显示的解决方法
举个例子 Map < String , Object > jsonMap = new HashMap< String , Object>(); jsonMap.put(&quo ...
- JSON语法及JSON定义规范化
版权声明:本文为博主原创文章,未经博主允许不得转载. https://www.cnblogs.com/zhuhui-site/p/10090541.html 一.前言 JSON(JavaScrip ...
- NOI 二分算法练习
1.NOI 二分法求函数的零点 总时间限制: 1000ms 内存限制: 65536kB 描述 有函数: f(x) = x5 - 15 * x4+ 85 * x3- 225 * x2+ 274 * ...
- CDOJ 1280 772002画马尾 每周一题 div1 矩阵快速幂 中二版
"问题:众所周知772002很喜欢马尾,所以他决定画几幅马尾送给他的女朋友. 772002会画m种马尾,772002还有n张纸,n张纸分别编号1到n,每张纸上只能画一种马尾. 然而77200 ...
- udev详解
转:http://www.360doc.com/content/10/0215/11/551936_15865336.shtml 如果你使用Linux比较长时间了,那你就知道,在对待设备文件这块,Li ...