时间复杂度问题
因为在刷leecode的时候涉及时间复杂度的问题,还是需要把本科学习的数据结构基础知识进行整理
1.4 算法及其复杂性
-
算法的复杂性
时间复杂性: 算法中基本操作重复执行的次数是问题规模n的某个函数f(n),随着问题规模n的增大,算法执行时间的增长率和f(n)的增长率相同,称作算法的渐进时间复杂性,
** 一个算法在执行过程中消耗的时间取决于下面的因素:**
(1)算法所需数据输入的时间
(2)算法编译为可执行程序的时间
(3)计算机执行每条指令所需的时间
(4)算法语句重复执行的次数
主要时间度量: 算法语句重复执行的次数 -
O后面的括号中有一个函数,指明某个算法的耗时/耗空间与数据增长量之间的关系。其中的n代表输入数据的量。
2.1 比如时间复杂度为O(n),表示数据量增大几倍,耗时也增大几倍,常见的遍历算法。
2.2 时间复杂度为O(n^2), 表示数据量增大n倍,耗时增大n的平方,比先行更高的时间复杂度。比如冒泡排序、选择排序, 对n个数排序,需要扫描n*n次,
2.3 比如O(logn),当数据量增大n倍时,耗时增大logn倍数(以2为底)比如,当数据增大256倍时,耗时只增大8倍,是比线性还要低的时间复杂度,二分法查找就是O(logn)的算法,每找一次排除一半的可能,256个数据中,只需要查找8次就可以找到目标同理O(nlogn)同理,就是n乘以logn,当数据增大256倍时,耗时增大256*8倍,这个复杂度高于线性,地域平方。归并排序就是O(nlogn)的时间复杂度。快速排序算法
2.4 O(1)就是最低的时空复杂度了,也就是耗时/耗空间与输入数据大小无关,无论输入数据增大多少倍,耗时/耗空间都不变。 哈希算法就是典型的O(1)时间复杂度,无论数据规模多大,都可以在一次计算后找到目标(不考虑冲突的话)
-
Hash 算法
哈希表就是一种以**键-值(key-indexed)**存储数据的结构,只需要输入带查找的值即key ,即可查找对应的值
使用哈西查找的两个步骤:3.1 使用哈希函数将被查找的键转换为数组的索引。在理想的情况下,不同的键会被转换为不同的索引值,但是有些情况下我们需要处理多个键被哈希到一个索引值的情况,因此哈希的第二个步骤处理冲突
3.2. 处理哈西碰撞冲突:拉链法和线性探测法
哈希表是在时间和空间上做出权衡的经典例子,如果没有内存限制,可以直接将键作为数组的索引,那么所有的查找时间复杂度为O(1):如果没有没存限制,可以使用无序数组并进行顺序查找,这样只需要很少的内存。哈希表使用了适度的空间和时间在两个极端找到了平衡。
构造哈希表的方法:这里博客https://blog.csdn.net/tanggao1314/article/details/51457585
介绍的很清楚,不再赘述:直接定址法,数字分析法,折叠法,平方取中法,减去法,基数转换法,除留余数法,随机数法,随机乘数法;字符串数值哈希法;旋转法
哈希处理冲突的方法
- 开放定址法(再散列法),基本思想是:当关键字key的哈希地址p=H(key)出现冲突时,以p为基础,产生另一个哈西地址p1,如果p1仍然冲突,再以p为基础,产生另一个哈西地址p2 ,,,,直到找到一个不冲突的哈希地址pi,将相应元素存入其中。这种方法有一个通用的再散列函数形式:
-
Hi=(H(key)+di)% m i=1,2,…,n
其中H(key)为哈希函数,m为表长,di为增量序列。增量序列的取值方式不同,相应的再散列方式也不同。主要有以下三种:
- 线性探测再散列:dii=1,2,3,…,m-1
- 二次探测再散列: di=12,-12,22,-22,…,k2,-k2 ( k<=m/2 )
- 伪随机探测再散列:di=伪随机数序列。