惊!世界上竟然有O(N)时间复杂度的排序算法!计数排序!
啥?你以为排序算法的时间复杂度最快也只能O(N*log(N))了?
O(N)时间复杂度的排序算法听说过没有?计数排序!!它是世界上最快最简单的算法!!!
计数排序算法操作起来只有三步,看完秒懂!
- 根据待排序集合中最大元素和最小元素的差值范围确定申请的桶个数;
- 遍历待排序集合,将每一个元素统计到对应的桶中;(此步完成后每个桶里面的数字代表了此桶对应元素出现的次数。)
- 从小到大遍历一遍所有桶,如果桶中有元素,那么就往排序结果里添加上对应个数的该桶对应的元素。
举个例子就明白了,假设已知所有待排序数字范围都在0~10,现在给了待排序的数组[5, 3, 5, 2, 8]。那么:
- 申请
0~10共11个桶用于放元素。 - 遍历待排序的数组
[5, 3, 5, 2, 8],把对应的桶里面放入小旗子,即 2、3、8 桶各放了一个旗子, 5 桶里放了两个旗子。 - 从 0 到 11 遍历一遍所有的桶,如果桶里没有小旗子就跳过,有小旗子就往结果里放入小旗子个数的该元素。得到
[2, 3, 5, 5, 8]。
是不是超级简单!
时间复杂度:数据取值范围是常数 M,待排序元素个数是 N,总的时间复杂度是 O(M + N) = O(N)!我们只把每个待排序的数字访问了一遍,所以是O(N)!
啥?你问我那 M 呢?M 是题目告诉你的数据取值范围呀,是个常数,和你要解决的问题规模无关!
空间复杂度:由于我们申请了大小为 M 的桶来放元素,所以空间复杂度是 O(M)。
啥?你问我那 N 呢?申请了 N 个空间用来存储要返回的结果,这个空间不算入空间复杂度!
既然计数排序的时间复杂度是 O(N) 那我们为啥不都使用计数排序呢?答案是只有当数字取值规模确定并且比较小的时候才能用呀,如果不知道取值规模或者取值规模太大,就不可以申请出那么多桶了呦~
本题告诉了取值范围是-50000 <= A[i] <= 50000,所以直接申请 100000 个桶就好了!
我们每个桶的下标是从 0 开始的,但是A[i]最小能取到 -50000,所以把 A[i] 映射到桶的下标的时候需要 + 50000;最后根据桶里面的元素放入到结果数组的时候要把桶的下标 - 50000还原成 A[i]。
我使用的C++代码作为演示。
class Solution {
public:
vector<int> sortArray(vector<int>& nums) {
int N = nums.size();
vector<int> counter(100010, 0);
for (int n : nums) {
counter[n + 50000] ++;
}
vector<int> res;
for (int i = 0; i < 100010; ++i) {
if (counter[i] != 0) {
res.insert(res.end(), counter[i], i - 50000);
}
}
return res;
}
};
欢迎关注负雪明烛的刷题博客,刷题800多,每道都记录了写法!
力扣每日一题活动建群啦,一起监督和讨论,我自建监督网址:http://group.ojeveryday.com/#/check,加入方式可以在监督网址中看到。
惊!世界上竟然有O(N)时间复杂度的排序算法!计数排序!的更多相关文章
- 一种O(n)时间复杂度的计数排序算法和Top N热词算法
排序算法是研究非常广泛且超级经典的算法,主流排序算法的时间复杂度基本都在O(nlogn). 今天就介绍一种以hash表为基础的,时间复杂度能够达到O(n)的排序算法--计数排序: 同时基于它的思想,完 ...
- 十大排序算法时间复杂度 All In One
十大排序算法时间复杂度 All In One 排序算法时间复杂度 排序算法对比 Big O O(n) O(n*log(n)) O(n^2) 冒泡排序 选择排序 插入排序 快速排序 归并排序 基数排序 ...
- Nivo Slider - 世界上最棒的 jQuery 图片轮播插件
Nivo Slider 号称世界上最棒的图片轮播插件,有独立的 jQuery 插件和 WordPress 插件两个版本.目前下载量已经突破 1,800,000 次!jQuery 独立版本的插件主要有如 ...
- Hacker - 世界上第一个黑客
http://juliet.iteye.com/blog/176525凯文·米特尼克,1964年生于美国加州的洛杉矶. 13岁时他对电脑着了迷,掌握了丰富的计算机知识和高超的操作技能,但却因为用学校的 ...
- 为什么我会认为SAP是世界上最好用最牛逼的ERP系统,没有之一?
为什么我认为SAP是世界上最好用最牛逼的ERP系统,没有之一?玩过QAD.Tiptop.用友等产品,深深觉得SAP是贵的有道理! 一套好的ERP系统,不仅能够最大程度承接适配企业的管理和业务流程,在技 ...
- 世界上不存在什么RedBSD,SuseBSD或者ArchBSD,Turb...
世界上不存在什么RedBSD,SuseBSD或者ArchBSD,TurboBSD之类的东西.
- hdu---(4515)小Q系列故事——世界上最遥远的距离(模拟题)
小Q系列故事——世界上最遥远的距离 Time Limit: 500/200 MS (Java/Others) Memory Limit: 65535/32768 K (Java/Others)T ...
- Git是目前世界上最先进的分布式版本控制系统
一:Git是什么? Git是目前世界上最先进的分布式版本控制系统. 二:SVN与Git的最主要的区别? SVN是集中式版本控制系统,版本库是集中放在中央服务器的,而干活的时候,用的都是自己的电脑,所以 ...
- 世界上最方便的SharePoint移动客户端--Rshare
Rshare我试用了一段时间,同时也测试了其他家产品,使用后的感觉是Rshare无愧于世界上最方面的SharePoint移动客户端. 1.界面设计很方便,设计中充分考虑到移动客户的使用习惯及喜好,设计 ...
随机推荐
- Matlab指针数组
Matlab指针数组 前面博客Matlab指针中介绍了如何在Matlab中使用handle类型对象作为指针使用,本文则介绍一些使用这些类型指针的小技巧. 自定义类型的指针数组 在大部分编程语言中,我们 ...
- expr判断是否为整数
判断一个变量值或字符串是否为整数 原理:利用expr计算时变量或字符串必须为整数的规则,把变量和一个整数(非零) 相加,判断命令返回是否为0,0--成功为整数 #!/bin/bash expr $1 ...
- Centos7服务器上RabbitMQ单机安装
一.背景 最近项目中用到了RabbitMQ,但是发现自己本地没有安装,此文记录一下本地RabbitMQ的安装过程.注意不同的系统安装方式略有不同,此处我们记录的是Centos7的安装方式. 二.安装方 ...
- 学习java 7.23
学习内容: 前面讲解了如果构建GUI界面,其实就是把一些GUI的组件,按照一定的布局放入到容器中展示就可以了.在实际开发中,除了主界面,还有一类比较重要的内容就是菜单相关组件,可以通过菜单相关组件很方 ...
- Flink(八)【Flink的窗口机制】
目录 Flink的窗口机制 1.窗口概述 2.窗口分类 基于时间的窗口 滚动窗口(Tumbling Windows) 滑动窗口(Sliding Windows) 会话窗口(Session Window ...
- CSS系列,清除浮动方法总结
在非IE浏览器(如Firefox)下,当容器的高度为auto,且容器的内容中有浮动(float为left或right)的元素.在这种情况下,容器的高度不能自动伸长以适应内容的高度,使得内容溢出到容器外 ...
- git 日志技术
1.git log, 在一个分支下, 以时间的倒序方式显示你制造的所有commit列表,包含创建人,时间,提交了什么等信息: 2. git reflog, 获取您在本地repo上还原commit所做工 ...
- javaAPI1
Iterable<T>接口, Iterator<T> iterator() Collection<E>:接口,add(E e) ,size() , Object[] ...
- java中super的几种用法,与this的区别
1. 子类的构造函数如果要引用super的话,必须把super放在函数的首位. class Base { Base() { System.out.println("Base"); ...
- android 调用相机拍照及相册
调用系统相机拍照: private Button btnDyxj; private ImageView img1; private File tempFile; btnDyxj = (Button) ...