文章目录
数据结构和算法基本概念
算法是什么?
- 算法是一系列解决问题的清晰指令,是计算机处理信息的本质!
- 算法是独立存在的一种 解决问题的方法和思想!
解题的四步骤
- 分析需求
- 设计算法
- 代码实现
- 验证结果
例题
如果
a
+
b
+
c
=
1000
,
且
a
2
+
b
2
=
c
2
(
a
,
b
,
c
为自然数
)
,
如何求所有的
a
、
b
、
c
可能的组合?
如果a+b+c=1000,且a^2+b^2=c^2(a,b,c为自然数),\\如何求所有的a、b、c可能的组合?
如果a+b+c=1000,且a2+b2=c2(a,b,c为自然数),如何求所有的a、b、c可能的组合?
-
分析需求
找出所有a、b、c满足上述条件的组合
-
设计算法
尝试a、b、c的所有的组合,判断每个组合是否满足上述两个条件,如果满足输出,否则继续判断下面的组合(枚举法)
-
代码实现
# @Author :泰敢人辣 # Date :2023/7/20 10:35 import time s_time = time.time() for a in range(0,1001): for b in range(0,1001): for c in range (0,1001): if a + b + c == 1000 and a ** 2 +b ** 2 == c ** 2: print(f'符合条件的组合为{a}、{b}、{c}') e_time = time.time() print(f'程序执行了{s_time-e_time}') #输出结果如下 ''' 符合条件的组合为0、500、500 符合条件的组合为200、375、425 符合条件的组合为375、200、425 符合条件的组合为500、0、500 程序执行了-68.64588284492493 '''
-
验证结果
显然使用枚举法进行一亿次的计算是可以得到结果的
但是用时一分多钟,效率低下,故这种方法不可取,需要设计更为精妙的算法!
算法的特性
- 输入项:算法具有0个或多个输入
- 输出项:算法至少有1个输出
- 有穷性:算法必须能在有限个步骤后终止,并且需要在可接受的时间内
- 准确性:算法的每一步骤必须有确切的定义
- 可行性:算法的每一步都是可行的
时间复杂度!!!
基于上面的例题代码:
框中的表达式是否需要知道每一个c的值?仔细想一想显然是吗,没有必要的吧!
反过来想一下,如果满足条件的c必然满足上面的等式,即:
c
=
1000
−
a
−
b
c=1000-a-b
c=1000−a−b
此时我们只用两个遍历即可
# @Author :泰敢人辣
# Date :2023/7/20 10:35
import time
s_time = time.time()
for a in range(0,1001):
for b in range(0,1001):
c = 1000 - a -b
if a ** 2 +b ** 2 == c ** 2:
print(f'符合条件的组合为{a}、{b}、{c}')
e_time = time.time()
print(f'程序执行了{s_time-e_time}')
'''代码运行结果如下'''
'''
符合条件的组合为0、500、500
符合条件的组合为200、375、425
符合条件的组合为375、200、425
符合条件的组合为500、0、500
程序执行了-0.48239660263061523
'''
可以很明显的看到只用了不到1秒的时间就运行结束!!!
引入时间复杂度
对于程序的运行时间每次可能都会不一样,显然我们用运行时间来判定算法程序的好坏显然是不明智的!
程序运行的时间不一样,但是程序运行的步骤是一样子的!故我们可以用步骤的多少来描述算法
定义 时间频度 为程序运行的步骤,用T表示
for a in range(0,1001):
for b in range(0,1001):
for c in range (0,1001):
if a + b + c == 1000 and a ** 2 +b ** 2 == c ** 2:
print(f'符合条件的组合为{a}、{b}、{c}')
计算上述代码的时间频度:
T
=
1000
×
1000
×
1000
×
2
T = 1000\times1000\times1000\times2
T=1000×1000×1000×2
当问题的数据规模(n)
发生变化时,时间频度T也会跟着变化,其通式为:
T
=
n
3
×
2
T=n^3\times2
T=n3×2
时间复杂度的定义及其简单计算
定义时间复杂度(渐进时间复杂度),描述随着问题的数据规模增长,算法的时间频度的增长趋势
。记作:
O
(
F
(
n
))
其中
F
(
n
)时
T
(
n
)的渐进函数
O(F(n))\\其中F(n)时T(n)的渐进函数
O(F(n))其中F(n)时T(n)的渐进函数
在时间频度T的通式中,当n趋向于无穷大的时候,谁的值最大,谁就是时间复杂度!!!
例如:
T
=
n
3
×
2
其中的时间复杂度为:
O
(
n
3
)
T=n^3\times2\\其中的时间复杂度为:O(n^3)
T=n3×2其中的时间复杂度为:O(n3)
计算时的注意点
- 计算时,往往只关注时间频度中的最高次项其他次要项和
常数
项忽略顺序结构,时间复杂度按加法来计算
循环结构,时间复杂度按乘法来计算
分支结构,时间复杂度取最大值
- 没有特殊说明时,算法的时间复杂度都是指最坏的时间复杂度
常见的时间复杂度
时间频度举例 | 阶 | 非正式术语 |
---|---|---|
12 | O(1) | 常数阶 |
2n+3 | O(n) | 线性阶 |
3n2 + 2n + 1 | O(n2) | 平方阶 |
5log2n+20 | O(logn) | 对数阶 |
2n+3nlog2n+19 | O(nlogn) | nlogn阶 |
6n3+2n2+3n+4 | O(n3) | 立方阶 |
2n | O(2n) | 指数阶 |
![]() |
列表字典常用操作的时间复杂度
列表中添加元素的方法
a = []
#方法1
a += [1]
'''
方法1等同于 a.extend([1])
'''
#方法二
a = a + 1
'''
方法二每次执行的时候都会重新创建内存地址 特别慢
'''