猜数游戏

1-100,猜一个我心中的数字?
第一次猜多少? 50
最多猜几次? 7次 2^7 = 128
1- 1000 猜几次? 2^10 = 1024
1 - 1000000猜几次 2 ^20 > 1000000
100 - 1000 - 1000000 变化很大; 7 - 10 - 20 变化很小

  1. import time
  2. import random
  3. import matplotlib.pyplot as plt
  4. import math
  5. %matplotlib inline
  6. def random_list(l):
  7. return [[int( 1000*random.random()) for i in range(l*n)] for n in range(1,20)]

O(1)-Constant (常数级别)

  1. def squre(x):
  2. return x *x
  3. squre(3)
  1. def first(x): # x is a list
  2. start = time.time()
  3. r = x[0] # 取列表起始元素
  4. t = time.time - start
  5. return r, len(x), t
  6. def midle(x):
  7. start = time.time()
  8. r = x[len(x)//2] # 取列表中间元素
  9. t = time.time() - start
  10. return r, len(x), t
  11. def last(x):
  12. start = time.time()
  13. r = x[-1] # 取列表最后一个元素
  14. t = time.time() - start
  15. return r, len(x), t
  1. random_list = random_list(10000)
  2. rst = [last(l) for l in random_list]
  3. len(rst)
  4. rst

image.png

  1. x = list(zip(*rst))[1]
  2. y = list(zip(*rst))[2]
  3. plt.plot(x,y)

image.png
随着次数的增加的增加,时间基本此平在0.00。

O(log)-logarithm(对数级别)

二分查找就是log

  1. import bisect
  2. def bs(nums,target): # 二分查找
  3. sorted(nums)
  4. start = time.time()
  5. i = bisect.bisect_left(nums,target)
  6. if i != len(nums) and nums[i] == target:
  7. t = time.time() - start
  8. return i, len(nums), t
  9. t = time.time() - start
  10. return -1, len(nums), t
  1. random_lists = random_list(1000)
  2. rst = [bs(l,100) for l in random_lists]
  3. len(rst)
  4. rst

image.png

  1. x = list(zip(*rst))[1]
  2. y = list(zip(*rst))[2]
  3. plt.plot(x,y)

image.png
随着次数的增加的增加,时间基本也此平在0.00,**但是和O(1)还是有区别的。

O(n)- linear (线性级别)

  1. def find_max(l): # 找最大的数
  2. start = time.time()
  3. if l == None:
  4. return None
  5. mx = l[0]
  6. for n in l:
  7. if n > mx:
  8. mx = n
  9. t = time.time() - start
  10. return mx, len(l), t
  1. random_lists = random_list(20000)
  2. rst = [find_max(l) for l in random_lists]
  3. len(rst)
  4. rst

image.png

  1. x = list(zip(*rst))[1]
  2. y = list(zip(*rst))[2]
  3. plt.plot(x,y)

image.png

不规律是因为计算机实时的复核是不一样的。

O(nlgn)- linear logarithmic(线性对数级别)

  1. def mysort(l): # 排序
  2. start = time.time()
  3. l.sort()
  4. t = time.time() - start
  5. return l[0], len(l), t
  1. random_lists = random_list(20000)
  2. rst = [mysort(l) for l in random_lists]
  3. len(rst)
  4. rst

image.png

  1. x = list(zip(*rst))[1]
  2. y = list(zip(*rst))[2]
  3. plt.plot(x,y)

image.png

O(n)- square (平方级别)

  1. def has_duplicate(l): # 查看数组中是否有重复的数字
  2. start = time.time()
  3. rst = False
  4. for i in range(len(l)):
  5. for j in range(i+1, len(l)):
  6. if l[i] == l[j]:
  7. rst = True
  8. t = time.time() - start
  9. return rst, len(l), t
  1. random_lists = random_list(100)
  2. rst = [ has_duplicate(l) for l in random_lists]
  3. len(rst)
  4. rst

image.png

  1. x = list(zip(*rst))[1]
  2. y = list(zip(*rst))[2]
  3. plt.plot(x,y)

image.png

评估算法运行时间

  • a = 最快的基本操作所需的运行时间
  • b = 最慢的基本操作所需的运行时间
  • a(时间复杂度) <= T(n) <= b(时间复杂度)
  • 因此,运行时间T(n)在两个线性函数之间

    Big - O 记法

image.png

分析处算法的最差情况:比如1-100 最好猜1次中,一般猜4-5次,最差猜7次中,研究4, 5,7更有意义。

image.png
核心就是:根据多项式快速求出时间复杂度
例如: 5(N**2)-22NlogN + 5N + 2 —-> O(N2**)
3**NlogN + 5N —-> O(NlogN
image.png**

主项定理

image.png

image.png

image.png

**