【Sort】75. Sort Colors(计数排序、荷兰国旗问题)
来源:互联网 发布:百战天虫java 编辑:程序博客网 时间:2024/05/01 23:57
Given an array with n objects colored red, white or blue, sort them so that objects of the same color are adjacent, with the colors in the order red, white and blue.
Here, we will use the integers 0, 1, and 2 to represent the color red, white, and blue respectively.
Note:
You are not suppose to use the library's sort function for this problem.
Follow up:
A rather straight forward solution is a two-pass algorithm using counting sort.
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.
Could you come up with an one-pass algorithm using only constant space?
当然可以像这样一下就AC。。。。class Solution {public: void sortColors(vector<int>& nums) { sort(nums.begin(),nums.end()); }};
但是这个题想考什么呢。。。这里提到了counting sort(计数排序)
这是一种非比较排序算法,适用于待排序的数范围不大并且有很多重复的情况。算法思想很简单:如果知道了一堆数中有多少个数比a大,也就知道了a的位置(a是某个元素)。但是怎么通过非比较的方式去统计有多少个数比a大呢?答案是通过和数组下标建立映射关系。
假如有一堆数:0,0,0,1,1,2,2,2,2存在A数组里,现在考虑C数组:
C[0]、C[1]、C[2]、C[3]、C[4]、C[5]、C[6]、C[7]、C[8]、C[9]
初始化它们为0。然后我们遍历A,用C[A[i]]+=1来统计A[i]出现的次数(注意这里把待排序的A[i]转换成了C的下标),得到:
C[0]、C[1]、C[2]、C[3]、C[4]、C[5]、C[6]、C[7]、C[8]、C[9]
3、2、4、0、0、0、0、0、0
这个过程也反映了统计排序的一个劣势:如果待排序的数范围很大,那么空间的开销将非常大!
现在我们遍历C,做C[i]+=C[i-1],这就得到了有多少个小于等于A[i]的数的个数。
最后我们用一个数组B来保存结果,遍历A,做:B[C[A[j]]]=A[j]; C[A[j]]--;也就是找到A[j]合适的位置,把A[j]放进去,同时减小负责计数的C。这里虽然看上去复杂,但其实意思非常清晰:A[j]表示这个待排序的数,也是C的下标,C[A[j]]表示A[j]前面有多少个数小于等于它,那么C[A[j]]就是A[j]在B中的新位置(因为是小于等于,它自己也被包括了,所以位置是C[A[j]])。
以上就是计数排序的思路。
所以这个题就这样解决啦:
class Solution {public: void sortColors(vector<int>& nums) { vector<int> counter(3,0); vector<int> res(nums.size(),0); for(int i=0;i<nums.size();i++) counter[nums[i]]++;//count the number of 0s,1s and 2s for(int i=1;i<counter.size();i++) counter[i]+=counter[i-1];//now counter[i]=the number of elements greater than or equal to nums[i] for(int i=nums.size()-1;i>=0;i--){ res[counter[nums[i]]-1]=nums[i]; counter[nums[i]]--; } nums=res; }};需要注意。。。上面的过程参考了《算法导论》,A的下标是从1开始的,但实际编程下标都是从0开始,所以
res[counter[nums[i]]-1]=nums[i];这里要减1。
这个题的follow-up很有意思:
如何one-pass解决掉它?
class Solution {public: void sortColors(vector<int>& nums) { int j=0,k=nums.size()-1; for(int i=0;i<=k;i++){ if(nums[i]==0) swap(nums[i],nums[j++]); else if(nums[i]==2) swap(nums[i--],nums[k--]); } }};这其实就是大名鼎鼎的荷兰国旗问题了(Dutch Nation Flag Problem),可以参考:https://en.wikipedia.org/wiki/Dutch_national_flag_problem
- 【Sort】75. Sort Colors(计数排序、荷兰国旗问题)
- 75. Sort Colors--荷兰三色国旗问题
- LeetCode | Sort Colors(荷兰国旗问题)
- [LeetCode] 荷兰国旗问题 Sort Colors
- 【python】LeetCode | Sort Colors(荷兰国旗问题)
- Sort Colors(荷兰旗问题)
- 荷兰国旗问题 将3种数中重复数聚集 Sort Colors
- LeetCode 75. Sort Colors(颜色排序)
- 三色排序(荷兰国旗问题)
- 荷兰国旗问题,三色排序
- [leetcode] 【排序】 75. Sort Colors
- [leetcode-排序]--75. Sort Colors
- 75. Sort Colors--数组排序
- 75. Sort Colors 快速排序
- 「巧妙的计数」丑数问题、sort colors等排序问题
- [C++]LeetCode: 127 Sort Colors (计数排序 & 快速排序)
- Sort Colors 颜色排序
- 【排序】Sort Colors
- C++ review day1
- CentOS7 Solr6.6 集群部署
- 使用installr升级R至最新版本
- 构造函数模式
- jquery中的$(document).ready(function(){})和$(window).load()比较
- 【Sort】75. Sort Colors(计数排序、荷兰国旗问题)
- Chrome谷歌浏览器Flash开启⾃动运⾏指引
- emmet 一些用法
- JAVAEE第15天-static,final关键字,访问权限修饰符,内部类,静态代码块,包的声明和导入
- 学习广度优先搜索(Queue)
- 7.5提取联通区域的轮廓
- Bellman-ford最短路算法
- android中build.gradle文件简单说明
- 构造函数模式扩展