[算法系列之十一]荷兰国旗问题
【问题】
现有红白蓝三个不同颜色的小球,乱序排列在一起,请重新排列这些小球,使得红白蓝三色的同颜色的球在一起。这个问题之所以叫荷兰国旗问题,是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗。
【分析】
这个问题我们可以将这个问题视为一个数组排序问题。红白蓝分别对应数字0、1、2。红、白、蓝三色小球数量并不一定相同。
【思路一】
First, iterate the array counting number of 0's, 1's, and 2's, then overwrite array with total number of 0's, then 1's and followed by 2's.
(1)遍历数组,统计红白蓝三色球(0,1,2)的个数
(2)根据红白蓝三色球(0,1,2)的个数重排数组
时间复杂度:O(n)
【代码一】
/**------------------------------------* 日期:2015-02-02* 作者:SJF0115* 题目: 75.Sort Colors* 网址:https://oj.leetcode.com/problems/sort-colors/* 结果:AC* 来源:LeetCode* 博客:---------------------------------------**/class Solution {public:void sortColors(int A[], int n) {if(n <= 1){return;}//if// 统计个数int red = 0,white = 0,blue = 0;for(int i = 0;i < n;++i){if(A[i] == 0){++red;}//ifelse if(A[i] == 1){++white;}//elseelse{++blue;}//else}//for// 重新布局for(int i = 0;i < n;++i){if(red > 0){A[i] = 0;--red;}//ifelse if(white > 0){A[i] = 1;--white;}//elseelse{A[i] = 2;}}//for}};
【思路二】
我们可以把数组分成三部分,前部(全部是0),中部(全部是1)和后部(全部是2)三个部分,每一个元素(红白蓝分别对应0、1、2)必属于其中之一。
将前部和后部各排在数组的前边和后边,中部自然就排好了。
设置两个指针begin指向前部的末尾的下一个元素(刚开始默认前部无0,所以指向第一个位置),end指向后部开头的前一个位置(刚开始默认后部无2,所以指向最后一个位置),然后设置一个遍历指针current,从头开始进行遍历。
(1)若遍历到的位置为1,则说明它一定属于中部,根据总思路,中部的我们都不动,然后current向前移动一个位置。
(2)若遍历到的位置为0,则说明它一定属于前部,于是就和begin位置进行交换,然后current向前移动一个位置,begin也向前移动一个位置(表示前边的已经都排好了)。
(3)若遍历到的位置为2,则说明它一定属于后部,于是就和end位置进行交换,由于交换完毕后current指向的可能是属于前部的,若此时current前进则会导致该位置不能被交换到前部,所以此时current不前进。而同1),end向前移动一个位置。
【代码二】
/**------------------------------------* 日期:2015-02-04* 作者:SJF0115* 题目: Sort Colors* 网址:https://oj.leetcode.com/problems/sort-colors/* 博客:---------------------------------------**/class Solution {public:void sortColors(int A[], int n) {int begin = 0,end = n-1,cur = 0;while(cur <= end){if(A[cur] == 0){swap(A[begin],A[cur]);// 指向排序0末尾的下一个位置++begin;// 向前遍历++cur;}//ifelse if(A[cur] == 1){++cur;}//elseelse{swap(A[end],A[cur]);// 指向排序2开头的前一个位置--end;}//else}//for}};
【思路三】
用三个变量记录red,white,blue的下标位置。起始下标都为-1
如果A[i] == 0 ,插入red对white blue有影响,blue先整体向后移动一位,white再整体向后移动一位,如果不移动,前面插入的数据就会覆盖已有的。
如果A[i] == 1,插入white对blue有影响,blue整体向后移动一位。
A[i] == 2,直接插入blue
【代码三】
/**------------------------------------* 日期:2015-02-03* 作者:SJF0115* 题目: 75.Sort Colors* 网址:https://oj.leetcode.com/problems/sort-colors/* 结果:AC* 来源:LeetCode* 博客:---------------------------------------**/class Solution {public:void sortColors(int A[], int n) {if(n <= 1){return;}//ifint red = -1,white = -1,blue = -1;for(int i = 0;i < n;++i){// 插入red对white blue有影响if(A[i] == 0){// blue整体向后移动一位A[++blue] = 2;// white整体向后移动一位A[++white] = 1;// 插入redA[++red] = 0;}//if// 插入white blue受到影响else if(A[i] == 1){// blue整体向后移动一位A[++blue] = 2;// 插入whiteA[++white] = 1;}//else// 插入blue对其他没有影响else{// 插入blueA[++blue] = 2;}//else}//for}};
引用:http://www.cnblogs.com/gnuhpc/archive/2012/12/21/2828166.html
[算法系列之十一]荷兰国旗问题相关推荐
- 【算法系列之十一】k个一组翻转链表
给出一个链表,每 k 个节点一组进行翻转,并返回翻转后的链表. k 是一个正整数,它的值小于或等于链表的长度.如果节点总数不是 k 的整数倍,那么将最后剩余节点保持原有顺序. 示例 : 给定这个链表: ...
- Algorithm:C+语言实现之数组相关算法(和为定值的两个数、和为定值的m个数、荷兰国旗、长度为2n的洗牌算法、任意长度数组的洗牌算法)
Algorithm:C+语言实现之数组相关算法(和为定值的两个数.和为定值的m个数.荷兰国旗.长度为2n的洗牌算法.任意长度数组的洗牌算法) 目录 数组 1.寻找和为定值的两个数 2.和为定值的m个数 ...
- 【Algorithm】算法设计与分析(第二版)- 王红梅 - JAVA / C++实现:3.9 荷兰国旗问题
题目 : 荷兰国旗问题.要求重新排列一个由字符R,W,B(R代表红色,W代表白色,B代表兰色,这都是荷兰国旗的颜色)构成的数组,使得所有的R都排在最前面,W排在其次B排在最后.为荷兰国旗问题设计一个算 ...
- 各种排序算法以及扩展(选择排序,冒泡排序,插入排序,归并排序,最小和问题,堆排序,荷兰国旗问题,快速排序)
文章目录 基础算法一二课 选择排序 冒泡排序 插入排序 判断数据是否在数组中 找满足>=value的最左位置 ^ 异或符号的多用 一.进行交换 二.数组中有一种数出现了奇数次,其他数都出现了偶数 ...
- 算法练习day4——190321(小和、逆序对、划分、荷兰国旗问题)
归并排序快的原因: 后面的排序利用了前面排序的结果!!! 1.小和问题 在一个数组中, 每一个数左边比当前数小的数累加起来, 叫做这个数组的小和. 求一个数组的小和. 例子:[1,3,4,2,5] 1 ...
- 【算法习作】荷兰国旗问题
1.问题描述: 我们将乱序的红白蓝三色小球排列成有序的红白蓝三色的同颜色在一起的小球组.这个问题之所以叫荷兰国旗,是因为我们可以将红白蓝三色小球想象成条状物,有序排列后正好组成荷兰国旗. 2. ...
- 【算法】荷兰国旗问题
本文为博主九师兄(QQ:541711153 欢迎来探讨技术)原创文章,未经允许博主不允许转载. 文章目录 1.概述 2.问题一 2.1 暴力方法 2.2 双指针方法 1.2 问题二(荷兰国旗问题) 1 ...
- 【Python算法系列十一】二叉树的3种遍历方式
二叉树的遍历是指从根结点出发,按照某种次序依次访问二叉树中所有结点,使得每个结点被访问一次且仅被访问一次. 遍历二叉树的方法主要分 3 种:先序遍历.中序遍历和后序遍历: 先序遍历指最先遍历节点本身, ...
- C++入门算法荷兰国旗
荷兰国旗说的其实是一个二分类问题,就是红.白双球分类,同类要挨着的问题 /* Note:Your choice is C IDE */ #include "stdio.h" #de ...
最新文章
- linux下ipmitool路径,Linux中的ipmitool工具的使用
- GDCM:gdcm::Orientation的测试程序
- [攻防世界 pwn]——monkey
- 商品尺码规格和颜色需要支持双引号
- Linux 字符设备驱动开发基础(五)—— ioremap() 函数解析
- C# 数据的加密解密
- 通过负载均衡器+域名实现容灾切换-(8)基于DNS解析的GSLB在BS架构中应用实践(转)(2)...
- web 导出文件时如何让用户选择路径_Visual Paradigm 教程[UML]:如何绘制动画UML活动图?...
- python字典返回键值对_从Python字典对象中提取键值对的子集?
- ASP 中健壮的页结构的异常处理
- 析构函数的标量与矢量?
- 介质天线的设计原理_以水为媒介的介质天线的制作方法
- recovery_minui解说
- python ——时间间隔
- vue的provide的使用
- 刘道成 mysql 课件_燕十八公益讲堂mysql.ppt
- Windows XP系统正版验证出现的黑屏解决方法
- 家居O2O平台有哪些?
- 文科计算机有哪些专业,计算机有哪些专业
- SpringBoot实现代码生成器——基于SpringBoot和Vue的后台管理系统项目系列博客(十)