Python基础(十四) Python之禅与时间复杂度分析_快速找到最大值 时间复杂度(1)

img
img

网上学习资料一大堆,但如果学到的知识不成体系,遇到问题时只是浅尝辄止,不再深入研究,那么很难做到真正的技术提升。

需要这份系统化的资料的朋友,可以添加戳这里获取

一个人可以走的很快,但一群人才能走的更远!不论你是正从事IT行业的老鸟或是对IT行业感兴趣的新人,都欢迎加入我们的的圈子(技术交流、学习资源、职场吐槽、大厂内推、面试辅导),让我们一起学习成长!

plt.figure(figsize=(12, 6))
for method, method_label in zip(methods, method_labels):
plt.plot(t, method(t), label=method_label, lw=3)
plt.xlim(1, 20)
plt.ylim(0, 40)
plt.legend()



<matplotlib.legend.Legend at 0x22728098e80>


![image-20221003194339678](https://img-blog.csdnimg.cn/img_convert/821524c3f1ad8d60511b75ff95760a04.png)


**我们的最爱:常数函数和对数函数**


**勉强接受:线性函数和nlogn函数**


**难以承受:平方函数和指数函数**


##### 14.2.2 三集不相交问题


问题描述:


假设有A、B、C三个序列,任一序列内部没有重复元素,欲知晓三个序列交集是否为空



import random
def creat_sequence(n):
A = random.sample(range(1, 1000), k=n)
B = random.sample(range(1000, 2000), k=n)
C = random.sample(range(2000, 3000), k=n)
return A, B, C



A, B, C = creat_sequence(100)
def no_intersection_1(A, B, C):
for a in A:
for b in B:
for c in C:
if a == b == c:
return False
return True

%timeit no_intersection_1(A, B, C)
no_intersection_1(A, B, C)



36.7 ms ± 2.12 ms per loop (mean ± std. dev. of 7 runs, 10 loops each)

True



def no_intersection_2(A, B, C):
for a in A:
for b in B:
if a == b: # 如果相等再进行遍历,否则就返回上一级
for c in C:
if a == c:
return False
return True

%timeit no_intersection_2(A, B, C)



301 µs ± 37.9 µs per loop (mean ± std. dev. of 7 runs, 1000 loops each)



import time

res_n_3 = []
res_n_2 = []

for n in [10, 20, 100]:
A, B, C = creat_sequence(n)
start_1 = time.time()
for i in range(100):
no_intersection_1(A, B, C)
end_1 = time.time()
for i in range(100):
no_intersection_2(A, B, C)
end_2 = time.time()
res_n_3.append(str(round((end_1 - start_1)*1000))+“ms”)
res_n_2.append(str(round((end_2 - end_1)*1000))+“ms”)

print(“{0:<23}{1:<15}{2:<15}{3:<15}”.format(“方法”, “n=10”, “n=20”, “n=100”))
print(“{0:<25}{1:<15}{2:<15}{3:<15}”.format(“no_inte rsection_1”, *res_n_3))
print(“{0:<25}{1:<15}{2:<15}{3:<15}”.format(“no_intersection_2”, *res_n_2))



方法 n=10 n=20 n=100
no_inte rsection_1 6ms 42ms 4001ms
no_intersection_2 0ms 1ms 24ms


##### 14.2.3 元素唯一性问题


问题描述:A 中的元素是否唯一



def unique_1(A):
for i in range(len(A)):
for j in range(i+1, len(A)):
if A[i] == A[j]:
return False
return True



def unique_2(A):
A_sort = sorted(A)
for i in range(len(A_sort)-1):
if A[i] == A[i+1]:
return False
return True


时间复杂度为O(nlogn)



import random
res_n_2 = []
res_n_log_n = []

for n in [100, 1000]:
A = list(range(n))
random.shuffle(A)
start_1 = time.time()
for i in range(100):
unique_1(A)
end_1 = time.time()
for i in range(100):
unique_2(A)
end_2 = time.time()
res_n_2.append(str(round((end_1 - start_1)*1000))+“ms”)
res_n_log_n.append(str(round((end_2 - end_1)*1000))+“ms”)

print(“{0:<13}{1:<15}{2:<15}”.format(“方法”, “n=100”, “n=1000”))
print(“{0:<15}{1:<15}{2:<15}”.format(“unique_1”, *res_n_2))
print(“{0:<15}{1:<15}{2:<15}”.format(“unique_2”, *res_n_log_n))



方法 n=100 n=1000
unique_1 49ms 4044ms
unique_2 1ms 21ms


##### 14.2.4 第n个斐波那契数


a(n+2) = a(n+1) + a(n)



def bad_fibonacci(n):
if n <= 1:
return n
else:
return bad_fibonacci(n-2)+ bad_fibonacci(n-1)


###### O(2^n)



def good_fibonacci(n):
i, a, b = 0, 0, 1
while i < n:
a, b = b, a+b
i += 1
return a



3


###### O(n)



%timeit bad_fibonacci(10)



20.6 µs ± 1.15 µs per loop (mean ± std. dev. of 7 runs, 10000 loops each)



%timeit good_fibonacci(10)



875 ns ± 24.5 ns per loop (mean ± std. dev. of 7 runs, 1000000 loops each)


##### 14.2.5 最大盛水容器


![image-20221003194433772](https://img-blog.csdnimg.cn/img_convert/e2f503fa4b5ec3feebf894134513bb62.png)


**暴力求解——双循环**



def max_area_double_cycle(height):
“”“暴力穷举双循环”“”
i_left, i_right, max_area = 0,0,0
for i in range(len(height)-1):
for j in range(i+1, len(height)):
area = (j-i) * min(height[j], height[i])
if area > max_area:
i_left, i_right, max_area = i, j, area
return i_left, i_right, max_area

height = np.random.randint(1, 50, size=10)
print(height)
max_area_double_cycle(height)



[10 11 41 26 2 44 26 43 36 30]

(2, 8, 216)



import matplotlib.pyplot as plt

plt.bar(range(10), height, width=0.5)
plt.xticks(range(0, 10, 1))



([<matplotlib.axis.XTick at 0x22728e01b00>,
<matplotlib.axis.XTick at 0x227289ce518>,
<matplotlib.axis.XTick at 0x22728e01358>,
<matplotlib.axis.XTick at 0x22728f38c50>,
<matplotlib.axis.XTick at 0x22728f38b00>,
<matplotlib.axis.XTick at 0x22728f4f4a8>,
<matplotlib.axis.XTick at 0x22728f4f978>,
<matplotlib.axis.XTick at 0x22728f4fe48>,
<matplotlib.axis.XTick at 0x22728f60358>,
<matplotlib.axis.XTick at 0x22728f60828>],
<a list of 10 Text xticklabel objects>)


![image-20221003194400427](https://img-blog.csdnimg.cn/img_convert/67092bcf941eaab7759eec95f3c1e6d7.png)


**双向指针**



def max_area_bothway_points(height):
“”“双向指针法”“”

i = 0
j = len(height)-1
i_left, j_right, max_area=0, 0, 0
while i < j:
    area = (j-i) \* min(height[i], height[j])
    if area > max_area:
        i_left, j_right, max_area = i, j, area
    if height[i] == min(height[i], height[j]):
        i += 1
    else:
        j -= 1
return i_left, j_right, max_area

max_area_bothway_points(height)



(2, 8, 216)



double_cycle = []
bothway_points = []

for n in [5, 50, 500]:
height = np.random.randint(1, 50, size=n)
start_1 = time.time()
for i in range(100):
max_area_double_cycle(height)
end_1 = time.time()
for i in range(100):
max_area_bothway_points(height)
end_2 = time.time()
double_cycle.append(str(round((end_1 - start_1)*1000))+“ms”)
bothway_points.append(str(round((end_2 - end_1)*1000))+“ms”)

print(“{0:<15}{1:<15}{2:<15}{3:<15}”.format(“方法”, “n=5”, “n=50”, “n=500”))
print(“{0:<13}{1:<15}{2:<15}{3:<15}”.format(“暴力循环”, *double_cycle))
print(“{0:<13}{1:<15}{2:<15}{3:<15}”.format(“双向指针”, *bothway_points))



方法 n=5 n=50 n=500
暴力循环 3ms 97ms 7842ms
双向指针 2ms 8ms 56ms


##### 14.2.6 是不是时间复杂度低就一定好?


![img](https://img-blog.csdnimg.cn/img_convert/79fd302e412d252d149024a999c439fe.png)
![img](https://img-blog.csdnimg.cn/img_convert/4d6f2e4af816e7418dd6bd1ad5789c6e.png)
![img](https://img-blog.csdnimg.cn/img_convert/a34d63c95a75cc63fca5b6ff5aae5593.png)

**既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!**

**由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新**

**[如果你需要这些资料,可以戳这里获取](https://bbs.csdn.net/topics/618658159)**

    56ms           

14.2.6 是不是时间复杂度低就一定好?

[外链图片转存中…(img-PKjyCcpK-1715529576509)]
[外链图片转存中…(img-mUUiEjr3-1715529576509)]
[外链图片转存中…(img-H0JiES1M-1715529576510)]

既有适合小白学习的零基础资料,也有适合3年以上经验的小伙伴深入学习提升的进阶课程,涵盖了95%以上Go语言开发知识点,真正体系化!

由于文件比较多,这里只是将部分目录截图出来,全套包含大厂面经、学习笔记、源码讲义、实战项目、大纲路线、讲解视频,并且后续会持续更新

如果你需要这些资料,可以戳这里获取

  • 34
    点赞
  • 50
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值