常见算法模板(python)

常见算法模板(python)

    • 二分搜索(实数搜索、整数搜索)
    • 前缀和、差分数组
    • 深度优先搜索DFS
    • 宽度优先搜索BFS
    • 并查集
    • 树状数组
    • 线段树
    • 稀疏表
    • 动态规划
    • (矩阵) 快速幂
    • 字符串匹配算法-KMP
    • Floyd算法
    • Dijkstra算法
    • Bellman-Ford算法
    • SPFA算法
    • Prim算法
    • Kruskal算法

二分搜索(实数搜索、整数搜索)

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6


def check(k):
#根据题目要求(难点)
    return True/False
#实数搜索    
def bin_float_search(l,r):
    while r-l>0.001:#精度
        mid = (l + r) / 2
        if check(mid) :
            l = mid
        else:
            r = mid
    mid = (l + r) / 2
    return mid

#整数搜索
def bin_int_search(l,r):
	while l<r:
  		mid=(l+r)>>1
  		if check(mid):
  			r=mid
  		else:
  			l=mid+1    
  	return mid

前缀和、差分数组

前缀和加速区间和计算
差分数组提高区间修改效率

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
sumof=[0]*(n+10)#前缀序列
diff=[0]*(n+10)#差分序列
nums=[0]+list(map(int,input().split()))
for i in range(1,n+1):
	sumof[i]=sumof[i-1] + nums[i]
	diff[i] = nums[i]-nums[i-1]
for i in range(m):
    #差分数组实现区间加法更新
    l, r = map(int, input().split())
    diff[l] += 1
    diff[r + 1] -= 1
#对差分数组求前缀和,得到修改后每个数字
for i in range(1, n + 1):
    s[i] = s[i - 1] + diff[i]

深度优先搜索DFS

基于递归实现深度优先搜索

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
def dfs(层数,参数):
	if :#终止条件
		return #回溯
	for :枚举下层状态
		if:#判断当前状态是否搜说过
			True#没有,则标记该状态
			dfs(层数+1,参数)
			False#回溯
	return

宽度优先搜索BFS

基于队列实现宽度优先搜索

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
start = input()
possible = []
experience = {start}
queue= [[start,0]]
while queue:
    old = queue.pop(0)
    for i in possible:
    #搜索下一步
        if  :#判断该状态是否合法
            if new_state == end:#判断是否结束搜索

                sys.exit(0)
            if new_state not in experience:#判断当前状态是否已经搜索
                experience.add(new_state)
                queue.append([new_state,step])
            

并查集

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
par=[i for i in range(n+1)]     #初始化
def find_father(x):            #并查集查找函数
    if par[x]==x:
    	return x
    par[x]=find_father(par[x])#路径压缩
    return par[x]

def unite(x:int,y:int):     #并查集组合函数
    fx=find_father(x) ; fy=find_father(y)
    if fx==fy:return
    else:
        par[fx]=fy


for i in range(1,n+1):      
    unite(i,int(input()))#根据条件添加关系,完成合并

树状数组

前缀和数组以 O ( 1 ) O(1) O(1)时间复杂度求解区间和,但设计问题需要多次修改数组时,前缀和数组不再适用,树状数组查询和修改的时间复杂度均为 O ( l o g n ) O(logn) O(logn)

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
def lowbit(x):
	return x&-x
def add(x,d):
	while x<n:
		tree[x]+=d
		x+=lowbit(x)
def sum(x):
	ans = 0
	while x>0:
		ans += tree[x]
		x-=lowbit(x)
	return ans
	

线段树

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
tree_sum = [0] * (maxn * 4)
tree_add = [0] * (maxn * 4)
#线段树模板
#利用左右儿子信息更新节点o
def push_up(o):
    tree_mi[o] = sum(tree_sum[o << 1], tree_sum[o << 1 | 1])
#利用节点o的lazy标记add更新左右儿子
def push_down(o):
    if tree_add[o] != 0:
        tree_add[o << 1] += tree_add[o]
        tree_sum[o << 1] += tree_add[o]
        tree_add[o << 1 | 1] += tree_add[o]
        tree_sum[o << 1 | 1] += tree_add[o]
        tree_add[o] = 0

#建树
def build(o, l, r):
    tree_add[o] = 0
    if l == r:
        tree_sum[o] = a[l]
        return
    mid = (l + r) >> 1
    build(o << 1, l, mid)
    build(o << 1 | 1, mid + 1, r)
    push_up(o)

#查询区间[L,R]的和
def query(o, l, r, L, R):
    if L <= l and r <= R:
        return tree_sum[o]
    push_down(o);
    mid = (l + r) >> 1
    ans = 1000000000;
    if L <= mid:
        ans +=query(o << 1, l, mid, L, R)
    if R > mid:
        ans +=query(o << 1 | 1, mid + 1, r, L, R)
    return ans

#区间更新[L,R]统一加上val
def update(o, l, r, L, R, val):
    if L <= l and r <= R:
        tree_sum[o] += val
        tree_add[o] += val
        return
    push_down(o);
    mid = (l + r) >> 1
    if L <= mid:
        update(o << 1, l, mid, L, R, val)
    if R > mid:
        update(o << 1 | 1, mid + 1, r, L, R, val)
    push_up(o);

稀疏表

牺牲 O ( l o g n ) O(logn) O(logn)的时间,使得后续每次查询区间最大值/最小值/公约数等的时间复杂度为 O ( 1 ) O(1) O(1)

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
def rmq_init(arr):
    arr_len = len(arr)
    exp = int(math.log(arr_len, 2))
    dp = [[0] * (exp + 1) for _ in range(arr_len + 1)]
    for i, a in enumerate(arr):
        dp[i + 1][0] = a
    for j in range(1, exp + 1):
        for start in range(1, arr_len + 1):
            if start + (1 << j) - 1 > arr_len:
                break
            dp[start][j] = max(dp[start][j - 1],
                               dp[start + (1 << (j - 1))][j - 1])
    return dp

def rmq_ask(dp, left, right):
    k = int(math.log(right - left + 1, 2))
    return max(dp[left][k], dp[right + 1 - (1 << k)][k])
	

动态规划

不滚动,交替滚动,自身滚动

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
#不滚动
T,M=map(int,input().split())
htime=[0]*(M+1)
hvalue=[0]*(M+1)
for i in range(1,M+1):
    htime[i],hvalue[i]=map(int,input().split())
dp=[[0]*(T+1) for i in range(M+1)]
for i in range(1,M+1):
    for j in range(0,T+1):
        if htime[i]>j:
            dp[i][j]=dp[i-1][j]
        else:
            npick=dp[i-1][j]
            pick=dp[i-1][j-htime[i]]+hvalue[i]
            dp[i][j]=max(npick,pick)
print(dp[M][T])


#交替滚动
T,M=map(int,input().split())
htime=[0]*(M+1)
hvalue=[0]*(M+1)
for i in range(1,M+1):
    htime[i],hvalue[i]=map(int,input().split())
dp=[[0]*(T+1) for i in range(2)]
new = 0
old = 1
for i in range(1,M+1):
    new,old = old,new
    for j in range(0,T+1):
        if htime[i]>j:
            dp[new][j]=dp[old][j]
        else:
            npick=dp[old][j]
            pick=dp[old][j-htime[i]]+hvalue[i]
            dp[new][j]=max(npick,pick)
print(dp[new][T])

#自身滚动
T,M=map(int,input().split())
htime=[0]*(M+1)
hvalue=[0]*(M+1)
for i in range(1,M+1):
    htime[i],hvalue[i]=map(int,input().split())
dp=[0]*(T+1)
for i in range(1,M+1):
    for j in range(T,htime[i]-1,-1):
        npick=dp[j]
        pick=dp[j-htime[i]]+hvalue[i]
        dp[j]=max(npick,pick)
print(dp[T])

(矩阵) 快速幂

改写*定义

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
class matrix:
    def __init__(self):
        self.m = [[0] * 205 for i in range(205)]
    def __mul__(self, other):
        res = matrix()
        for i in range(1, spn + 1):
            for j in range(1, spn + 1):
                for k in range(1, spn + 1):
                    res.m[i][j] = (res.m[i][j] +
                                   self.m[i][k] * other.m[k][j]) % MOD
        return res
def power(x: matrix, n: int):
    ans = matrix()
    for i in range(1, spn + 1):
        ans.m[i][i] = 1
    while n:
        if n & 1:
            ans = ans * x
        x = x * x
        n >>= 1
    return ans

字符串匹配算法-KMP

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
Next = [0]*N
def getNext(p):
    for i  in range(1,len(p)):
        j = Next[i]
        while j >0 and p[i] != p[j]:
            j = Next[i]
        if p[i]==p[j]:
            Next[i+1] =j+1
        else:
            Next[i+1] = 0
def kmp(s,p):
    ans =0
    j = 0
    for i in range(0,len(s)):
        while j>0 and s[i]!=p[j]:
            j =Next[j]
        if s[i] == p[j]:
            j+=1
            ans =max(ans,j)
        if j==len(p):
            return ans
    return ans

Floyd算法

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
dis = [[0 for _ in range(n)] for _ in range(n)]
for k in range(n):
	for i in range(n):
		for j in range(n):
			dis[i][j] = min(dis[i][j], dis[i][k] + dis[k][j])

Dijkstra算法

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
import heapq
def Dijkstra(s):
    done = [0 for  i  in range(n+1)]
    hp = []
    dis[s] = 0
    heapq.heappush(hp,(0,s))
    while hp:
        u =heapq.heappop(hp)
        if done[u]:
            continue
        done[u] = 1
        for i in range(len(G[u])):
            v,w=G[u][i]
            if done[v]:continue
            if dis[v]>dis[u]+w:
                dis[v]=dis[u]+w
                heapq.heappush(hp,(dis[v],v))
    

Bellman-Ford算法

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
def Bellman_Ford():
    for k in range(1, n + 1):
        for a, b, c in e:
            if b == n:
            dist[b] = min(dist[b], dist[a] + c)
    print(dist[n])

SPFA算法

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
import heapq
def spfa(s) :
    dis[s] = 0
    hp = []
    heapq. heappush(hp,s)
    inq=[0]*(n+1)
    inq[s]=1
    while hp:
        u = heapq. heappop(hp)
        inq[u]=0
        if dis[u]==INF : 
            continue
        for v,w in e[u]:
            if dis[v] > dis[u] + w :
                dis[v] = dis[u] + w
                if inq[v]==0:
                    heapq. heappush(hp,v)
                    inq[v]=1

Prim算法

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
def prime():
    ans = 0
    dis[1] = 0
    for i in range(1,n):
        x = 0
        for j in range(1,n+1):
            if not vis[j] and (x == 0 or dis[j] <dis[x]):
                x = j
        vis[x]=1
        for y in range(1,n+1):
            if not vis[y]:
                dis[y] = min(dis[y], e[x][y])
    for i in range(2,n+1):
        ans +=dis[i]

Kruskal算法

# -*- coding: utf-8 -*-
# @Author : BYW-yuwei
# @Software: python3.8.6
def getf(x):
    if x == f[x]:
        return x
    f[x] = getf(f[x])
    return f[x]
ecnt = n#连边数量
cnt = 0#生成树节点数量
ans = -1
e = sorted(e,key = lambda x:x[2])
for i in range(ecnt):
    u,v = getf(e[i][0]),getf(e[i][1])
    if u!=v:
        cnt+=1
        ans = max(ans,sqrt(e[i][2]))
        f[u] = v
        if cnt==n-1:
            break

你可能感兴趣的:(python,算法,深度优先)