数据结构与算法 | 0-引入

1 题目引入

题目:如果 a+b+c=1000,且 a2+b2=c^2(a,b,c 为自然数),如何求出所有a、b、c可能的组合?

1.1 暴力搜索

即枚举法!

import time

t0 = time.time()
for a in range(1001):
    for b in range(1001):
        for c in range(1001):
#             if a*a + b*b == c*c and a + b + c == 1000:
            if a**2 + b**2 == c**2 and a + b + c == 1000:
                print(a,b,c)

t1 = time.time()
print('所需时间为: ', t1-t0)
0 500 500
200 375 425
375 200 425
500 0 500

时间复杂度:O(n^3) 立方复杂度!

运行时间为:240s左右!

1.2 方法2

a b 有了 c肯定就直接出来了!就没必要再去搜索所有的了!直接赋值!

import time

t0 = time.time()
for a in range(1001):
    for b in range(1001):
        c = 1000 - a - b
        if a**2 + b**2 == c**2:
            print(a,b,c)

t1 = time.time()
print('所需时间为: ', t1-t0)
0 500 500
200 375 425
375 200 425
500 0 500
所需时间为:  1.0195651054382324

时间复杂度:O(n^2) 平方复杂度

2 Python算法本身复杂度

timeit模块可以用来测试一小段Python代码的执行速度。

class timeit.Timer(stmt=‘pass’, setup=‘pass’, timer=)

  • Timer是测量小段代码执行速度的类。

  • stmt参数是要测试的代码语句(statment);

  • setup参数是运行代码时需要的设置;

  • timer参数是一个定时器函数,与平台有关。

Timer类中测试语句执行速度的对象方法。number参数是测试代码时的测试次数,默认为1000000次。方法返回执行代码的平均耗时,一个float类型的秒数。

2.1 list的操作测试

import timeit
def test1():
    # + 操作
    l = []
    for i in range(1000):
        l = l + [i]
        
def test2():
    # append操作
    l = []
    for i in range(1000):
        l.append(i)
        
def test3():
    # 列表表达式
    l = [i for i in range(1000)]
    
def test4():
    # list方式
    l = list(range(1000))
def test6():
    # insert
    l = []
    for i in range(1000):
        l.insert(0,i)
from timeit import Timer
t1 = Timer("test1()", "from __main__ import test1")
print("concat ",t1.timeit(number=1000), "seconds")
concat  1.0583139009977458 seconds
t2 = Timer("test2()", "from __main__ import test2")
print("append ",t2.timeit(number=1000), "seconds")
append  0.09553768200566992 seconds

说明append比直接加会效率更高!

t3 = Timer("test3()", "from __main__ import test3")
print("comprehension ",t3.timeit(number=1000), "seconds")
comprehension  0.04220059799263254 seconds
t4 = Timer("test4()", "from __main__ import test4")
print("list range ",t4.timeit(number=1000), "seconds")
list range  0.013673824010766111 seconds

说明用list方法会比直接列表表达式效率更高

t6 = Timer("test6()", "from __main__ import test6")
print("insert range ",t6.timeit(number=1000), "seconds")
insert range  0.31473354900663253 seconds
  • 说明append比assert好!数据存储方式决定的!
  • 往头部添加比往尾部添加要慢得多!

综上:list方式是最好的!

2.2 pop操作测试

# 删除第一个元素
x = list(range(2000000))
pop_zero = Timer("x.pop(0)","from __main__ import x")
print("pop_zero ",pop_zero.timeit(number=1000), "seconds")
pop_zero  1.0132593379967147 seconds
# 删除最后一个元素
x = list(range(2000000))
pop_end = Timer("x.pop()","from __main__ import x")
print("pop_end ",pop_end.timeit(number=1000), "seconds")
pop_end  7.075899338815361e-05 seconds

头部删元素比尾部删元素慢得多!

3 列表和字典内置操作的时间复杂度

3.1 列表

在这里插入图片描述
重点:熟悉并记住下列内置函数的复杂度

  • 索引是1
  • append尾部追加是1
  • pop尾部删除是1
  • pop指定位置删除是n
  • insert指定位置插入是n
  • contains查询是n

3.2 字典

在这里插入图片描述

参考

猜你喜欢

转载自blog.csdn.net/qq_27782503/article/details/93138252
-0-