一、前言
自用为主
原帖来自 英雄哪里出来 (34条消息) 《画解数据结构》(0 - 1)- 算法时间复杂度_英雄哪里出来-CSDN博客
因为学校正在上数据结构Python语言实现,此贴只为记录学习的过程并且加深印象,不抄袭任何知识点内容只写代码部分。
如有错误请多指正。
二、穷举法
1、单层循环
给定n(n ≤ 1000)个元素ai,求其中奇数有多少个。
def countOdd(lst):
cnt = 0
for i in lst:
if i & 1:
cnt += 1
return cnt
时间复杂度O(n)
2、双层循环
给定n(n ≤ 1000)个元素ai,求有多少个二元组(i,j),满足ai + aj 是奇数(i < j)。
def countOddPair(lst):
cnt = 0
for i in range(len(lst) - 1):
for j in range(i + 1, len(lst)):
if (lst[i] + lst[j]) & 1:
cnt += 1
return cnt
时间复杂度O(n²)
3、三层循环
给定n(n ≤ 1000)个元素ai,求有多少个三元组(i,j,k),满足ai + aj + ak是奇数(i < j < k)。
def countOddTriple(lst):
cnt = 0
for i in range(len(lst)-1):
for j in range(i,len(lst)):
for k in range(j,len(lst)):
if (lst[i] + lst[j] + lst[k]) & 1:
cnt += 1
return cnt
时间复杂度O(n3)
4、递归枚举
给定n(n ≤ 1000)个元素ai和一个整数k(k ≤ n),求有多少个有序k元组,满足他们的和是偶数。
def dfs(lst, start, k, summ):
if k == 0:
return 0 if (summ & 1) else 1
s = 0
for i in range(start, len(lst)):
s += dfs(lst, i + 1, k - 1, summ + lst[i])
return s
强行实现了,但是不太理解,等以后学习了深度优先算法和递归再来仔细研究。
四、常见的时间复杂度
1、常数阶
一句话,略
2、对数阶
给定n(n ≤ 100000)个元素的有序数组ai和整数v,求v在数组中的下标,不存在输出-1。
def bin(lst, v):
r = len(lst) - 1
l = 0
while l <= r:
mid = (l + r) >> 1
if lst[mid] == v:
return mid
elif lst[mid] < v:
l = mid + 1
else:
r = mid - 1
return -1
二分查找,时间复杂度O(log2n)
ps:左移一位都相当于乘以2的1次方,左移n位就相当于乘以2的n次方。
右移一位相当于除2,右移n位相当于除以2的n次方。
3、根号阶
给定一个数n,问n是否是一个素数。
import math
def isPrime(n):
if n == 1:
return False
for i in range(2, int(math.sqrt(n)) + 1):
if n % i == 0:
return False
return True
时间复杂度O()
4、线性阶
O(n)
5、线性对数阶
给定n(n ≤ 100000)个元素ai,求满足ai + aj = 1024 的有序二元组(i , j)有多少对。
def search(lst, v, l):
r = len(lst) - 1
while l <= r:
mid = (l + r) // 2
if lst[mid] == v:
return True
elif lst[mid] < v:
l = mid + 1
else:
r = mid - 1
return False
def pair(lst):
lst.sort()
cnt = 0
for i in range(len(lst)):
a = lst[i]
b = 1024 - a
if search(lst, b, i):
cnt += 1
return cnt
时间复杂度O(nlog2n)
6、多项式阶
线性阶、平方阶、立方阶等
7、指数阶
给出n(n ≤ 15)个点,以及每两个点的关系(连通还是不连通),求一个最大的集合,使得在这个集合中都连通。
暂时不太理解题目如何实现,先放着。
8、阶乘阶
给定n(n ≤ 12)个点,并且给出任意两点间的距离,求从s点开始经过所有点回到的距离的最小值。
暴力枚举所有情况,全排列方案数n!
时间复杂度为O(n!)