1.什么是数据结构
数据结构(Data Structure)是计算机存储、组织数据的方式,指相互之间存在一种或多种特定关系的数据元素的集合
2.时间复杂度
2.1时间复杂度的概念
时间复杂度的定义:在计算机科学中,算法的时间复杂度是一个函数,它定量描述了该算法的运行时间,一个算法执行所耗费的时间,从理论上说,是不能算出来的,只有你把你的程序放在机器上跑起来,才能知道,但在实际中我们不可能吧每个算法都测试一变,说以才有了时间复杂度这个分析方法,一个算法所花费的时间与执行每一条语句成正比,算法中的基本操作的执行次数,为算法的时间复杂度。即找到某条语句与问题规模N之间的数学表达式,就可以估算这个算法的时间复杂度。
比如,我们熟悉的冒泡排序:
for(int i = 0;i<n;i++)
for(int j = 0 ;j<n;j++)
两层for循环 程序所执行的次数为nxn 数学表达式为F(N)=nxn 即时间复杂度为O(n^2),大概得估算,大O渐进表示法。
F(N)=n^2+2n+10
我们讨论一下n的取值
(1)当n取10时 F(N)=100+20+10=130
(2)当n取100时F(N) = 10000+200+10=10210
(3)当n取10000时F(N) = 100000000+20000+10=100020010
计算机的CPU跑的很快,最烂的也都能达到每秒上亿次,所以量级很小的我们都可以忽略不计
即F(N)=n^2+2n+10我们只看最大量级的,进行估算,也就是当N无穷大的时候2n+10直接可以忽略;只取量级最高的,即次算法的时间复杂度为O(n^2)
其它算法的时间复杂度也同样是这个道理。
常见的时间复杂度
5023266 | O(1) | 常数阶 |
3n+545 | O(n) | 性线阶 |
3n^2+2n+4545 | O(n^2) | 平方阶 |
3log2n+4 | O(logn) | 对数阶 |
2n+3log2n+4 | O(n*logn) | n*logn阶 |
n^3+2n^2+2n+56 | O(n^3) | 立方阶 |
2^n+n^3+2n+45 | O(2^n) | 对数阶 |
3.空间复杂度
3.1概念:空间复杂度也是一个数学表达式,是对一个算法在运行中临时占用存储空间大小的量度。空间复杂度不是程序占用了多少bytes的空间,因为这个也没太大意义,所以空间复杂度算的是变量的个数。空间复杂度计算规则基本跟实践复杂度类似,也使用大O渐进表示法。
注意:函数运行时所需要的栈空间(存储参数、局部变量、一些寄存器信息等)在编译期间已经确定好了,因此空间复杂度主要通过函数在运行时候显式申请的额外空间来确定。
3.2例如:
开辟一维数组 空间复杂度为O(n)或O(1)
计算机的运行内存已经越来越成熟,所以在实现算法的时候很少考虑到空间复杂度。
3.3常见的空间复杂度
O(1), O(n),O(n^2)(二维数组为代表)
4.经典例题
4.1带环问题
判断链表是否带环;我们可以用两个指针(快慢指针)进行判断 fast走两步,slow走一步
当进环时假设他们相差N步 每一次追及都会减少一步
追及次数 相差距离
1 N-1
2 N-2
3 N-3
......
N 0
因此最后两个指针一定会相遇 就可以判断出这个链表是否为带环。
问题 :那么当fast走3,4,5.......n步时呢还会判断出是否带环呢?两个指针是否会永远错过?
证明:当fast 走3步时
当进环时 假设环的周长为C 相差N步
(1)当N为偶数时 (2)当N为奇数时
追及次数 相差距离 追及次数 相差距离
1 N-2 1 N-2
2 N-4 2 N-4
3 N-6 3 N-6
......... .........
N-2 4 N-2 3
N-1 2 N-1 2
N 0 N -1
所以当他们相差偶数步时第一轮会追上 N为奇数时会错过C-1步
当C-1为偶数时 也就是他们之间相差偶数步,即N为偶数 C为奇数
追及次数 相差距离
1 N-2
2 N-4
3 N-6
......
N 0
第二轮就会追上
当C-1为奇数时 那么他们相差奇数步,即N为奇数 C为偶数
当再次循环追击时 每走完一圈fast总会在slow前面一步 他们永远相差奇数步,这时就会出现死循环;
此刻 我们得出一个结论 当N奇数,C为偶数时,fast和slow是永远不会相遇的
但真的会同时存在N为奇数,C为偶数的情况?
证明 slow的速度为v,则fast的速度的为3v ,在T=t时刻;
S s=vt Sf=3vt
得出fast走的路程为slow的3倍;
假设在t时刻slow走的路程为S
所以:3S=S+C*x+N
化简得:2S=C*x+N
2S永远为偶数 即当N为奇数,C为偶数时;C*x为偶数 C*x+N=偶+奇=奇
因此等式不成立
即反正出不可能同时存在N为奇数,C为偶数时;也就是 一定存在fast=slow的情况;
当fast的速度为slow的n倍时
等式为(n-1)S=C*x+N
排除同时存在N为奇数 C为偶数的情况不可能同时存在,其它情况都能存在且都能满足上面的式子
即不管fast先走多少步都会存在与slow相遇的情况;也就一定能判断出是否这个链表是否带环;
5.找出带环链表的入环节点
解法:两个指针,一个从头出发,一个从从相遇点出发
证明:
假设fast的速度为slow的两倍,slow走的路程为(L+N)
那么fast走的路程为2(L+N)
即:2(L+N)=L+N+C*X
化简得:L=C*X-N (X≥1,X∈N*)
所以当meet和start同时走的时候一定会在进环点相遇。
完
各位大佬多多评价多多指正;谢谢!