笔记(一)时间复杂度

学习地址:https://mp.weixin.qq.com/s/070nYGokM96aorZn6MZTDA

     https://u.geekbang.org/lesson/15?article=213888

  • 时间复杂度的计算

   (1)得出运行时间的函数                              

   (2)对函数进行简化  :

                 ①用常数1来取代所有加法常数 

    • ②修改后的函数中,只保留最高阶项           

      ③如果最高阶项存在且不是1,则忽略这个项的系数   

  • 时间复杂度大小关系

   O(1) < O(log n) < O(n) < O(nlog n) < O(n^2) < O(n ^3) < O(2^n) < O(n!) < O(n^n)

    写程序的时候一定对自己的程序的时间和空间复杂度有所了解。

 

  • 递归分析时间复杂度

  对递归画出一个递归树

  如个Fibonacci数列求n项和 f(n)=f(n-1) + f(n-2)   fib:0 1 1 2 3 5 8 13 21 ...

  直接递归求和:

int fib(int n)
{
     if(n < 2)
          return n;
     return fib(n-1) + fib(n-2);         
 
}

 

 求第6个数的fib和,会计算2^6次,呈指数型,时间复杂度为o(2^n) 是相当耗时的

可以增加一个缓存 将已经计算过的数据保存。不要重复计算。

通过go语言来算一下时间:

package main
import (
	"fmt"
	"time"
)

func fib(n int)int{
	if (n < 2) {
	  return n
	}
 
     return fib(n - 1) + fib(n - 2) } func main(){ start := time.Now() fmt.Println(fib(40)) end := time.Since(start) fmt.Println("run time:", end) }

 当n = 40时,运行时间为 575.960922 ms

 当n = 46时,运行时间为10.158493262 s

 可以看出随着n的增加,程序的运行时间增加的很多。

 

一般在递归的情形下有这么四种在面试和工程中使用到:

1、二分查找,一般发生在一个数列本身有序的时候,你要在有序的数列里找到你的目标数。只查一边这么下去的话,最后他的时间复杂度是log(n)。

2、如果是二叉树遍历的话,他的时间复杂度是O(n)。不通过主定理,简化的思考方式,二叉树遍历的话,我们会每一个节点都访问一次,而且仅访问一次。

3、在一个排好序的二维矩阵中进行二分查找。时间复杂度是O(n),如果是一维数组二分查找,时间复杂度是O(logn)

4、归并排序(merge sort),时间复杂度是nlogn的时间复杂度。

 

思考:

 1、手写二叉树遍历-前、中、后序,并分析时间复杂度。

答:O(n), 这里的n代表二叉树里边的树的节点总数。通过主定理得到;或者这么说不管是前序中序后续,二叉树里边的每个节点会访问一次且仅访问一次,所以它的时间复杂度线性于二叉树的节点总数,因此是O(n)

2、图的遍历:时间复杂度是多少?         答:O(n),这里的n的话是图里所有的节点总数。

3、搜索算法:DFS、BFS的时间复杂度? 答:不管是DFS(深度优先)、BFS(广度优先),时间复杂度都是O(n),这里的N指的就是搜索空间里边的节点总数。

4、二分查找:时间复杂度是多少?          答:log(n) 

 

 

 

 

 

 

 

                                     

 

posted on 2020-05-20 17:58  zz8781  阅读(121)  评论(0)    收藏  举报

导航