算法总结(python3)

这篇博客全面总结了Python3中的算法和数据结构,包括数组、链表、栈、队列、双端队列、优先队列等基础知识,以及哈希表、集合、二叉树等高级数据结构。此外,还涵盖了前缀和、递归、分治、回溯、搜索算法,如深度优先搜索、广度优先搜索和双向BFS。同时,讲解了动态规划在不同场景的应用,如股票买卖问题,以及字典树、并查集、位运算等实用算法。最后,介绍了排序算法,如快速排序、归并排序和堆排序。
摘要由CSDN通过智能技术生成

如果你使用的是Chrome,可以试试Ctrl+F搜索你想要找的内容!

主要是各种算法、数据结构的用法。

数组
a = []
a.append() #在后面添加
b = a.pop() #删除最后一个,并把最后一个返回给b
链表
class Node(object):
    def __init__(self, data):
        self.data = data
        self.next = None
stack = []
stack.append() #栈添加
last = stack.pop() #栈删除,并把删除元素返回
队列
queue = []
queue.insert(0,data) #队列添加
data= queue.pop() #队列删除,并把删除元素返回
双端队列
from collections import deque
deq = deque()
deq.append() #右侧添加
deq.appendleft() #左侧添加
data = deq.pop() #右侧删除
data = deq.popleft() #左侧删除

#使用双端队列实现栈
stack = deque()
stack.append() #添加
data = stack.pop() #删除

#使用双端队列实现队列
queue = deque()
queue.append() #添加
data = queue.popleft() #删除
优先队列
from queue import PriorityQueue
pd = PriorityQueue()
pd.put(value, priority) #添加,1级别最高
data = pd.get() #取出最高级
哈希表和映射
dic = {'a': 12, 'b': 23}
dic['c'] = 34 #添加
data = dic.get('a') #获得,如果不存在则返回None
dic.pop('a') #删除
集合
s = set() #创建一个无序不重复元素集,查询时间为O(1)
s.add(data) #添加
s.remove(data) #删除
二叉树
class TreeNode:
	def __init__(self, val=0, left=None, right=None):
		self.val = val
		self.left = left
		self.right = right
前缀和(和为k的子数组)
def subarraySum(self, nums: List[int], k: int) -> int:
	count = 0  #计数
	pre = 0  #前缀和
	lookup = {0:1}  #哈希表{前缀和:出现次数}
	for n in nums:
		pre += n
		if lookup.get(pre-k)!= None:
			count += lookup[pre-k]
		if lookup.get(pre)!= None:
			lookup[pre] += 1
		else:
			lookup[pre] = 1
	return count

递归
def recursion(level, param1, param2, ...):
	#递归终止条件
	if level > MAX_LEVEL:
		result.append() #result添加和处理
		return
	#当前层的逻辑处理部分
	
	...

	#进入下一层
	recursion(level+1, param1, param2, ...)

	#返回当前层状态
	return	
分治
def divide_conquer(problem, param1, param2, ...):
	#分治终止条件
	if problem is None:
		return value
	#当前层的逻辑处理部分
	data = prepare_data(problem)
	subs = split_problem(problem, data)
	#进入下一层计算子问题
	sub1 = divide_conquer(subs[0], param1, param2, ...)
	sub2 = divide_conquer(subs[1], param1, param2, ...)
	sub3 = divide_conquer(subs[2], param1, param2, ...)
	...
	#最终结果计算
	result = process_result(sub1, sub2, sub3, ...)
	return	result 
回溯
def backtracking(item = 0):
	#回溯终止条件
	if item == len(LIST):
		return True
	#当前层的逻辑处理部分
	index = prepare_index(item)
	#回溯
	for f in OUTSIDE_LIST(index):
		#改变result
		change_result(result)
		#进入下一层
		if recall(item+1):
			return True
		#回复刚刚改过的result
		reply_result(result)
	#返回当前层状态
	return	False
深度优先搜索
def dfs(node, visited): 
	if node in visited: #终止条件  	
		#这个节点已经拜访了     	
		return
	#记录拜访节点
	visited.add(node)
	#当前层的逻辑处理部分
	...	
	for next_node in node.children(): 		
		if next_node not in visited: 			
			dfs(next_node, visited)
广度优先搜索
#第一种写法
def BFS(root):
	visited = set()
	queue = []
	queue.append([root])
	while queue: 
		node = queue.pop()
		visited.add(node)
		process(node)
		nodes = generate_related_nodes(node)
		queue.push(nodes)
	#其他工作 

#第二种写法
def BFS(root):
	visited = set()
	queue = []
	queue.append(root)
	while queue: 
		child = []
		for node in queue:
			visited.add(node)
			process(node)
			nodes = generate_related_nodes(node)
			child.extend(nodes)
		queue = child
	#其他工作 
双向BFS
def DBFS(beginnode, endnode):
	visited = set()
	beginqueue= [beginnode]
	endqueue = [endnode]
	while beginqueue and endqueue: 
		if len(beginqueue) > len(endqueue):
			beginqueue, endqueue = endqueue, beginqueue
		child = []
		for node in beginqueue:
			visited.add(node)
			process(node)
			nodes = generate_related_nodes(node)
			if nodes in endqueue:
				return
			child.extend(nodes)
		queue = child
	#其他工作 
二分查找
left, right = 0, len(array)-1
while left <= right:
	mid = (left+right)/2
	if array[mid] == target:
		break or return result
	elif array[mid] < target:
		left = mid + 1
	else:
		right = mid - 1
动态规划方程(不同路径)
#自底向上

#递归
def dp(i,j,opt,a):
	if i == m and j == n:  #终止条件 
    	return 1
    	
	if opt[i][j]==0:
		if a[i][j] = None:
			opt[i][j] = dp(i+1,j,opt,a) + dp(i,j+1,opt,a)
		else:
			opt[i][j] = 0
			
	return opt[i][j]

#非递归
dp = triangle
for i in range(len(triangle)-2, -1, -1):
	for j in range(len(triangle[i])):
		dp[i][j] += min(triangle[i+1][j], triangle[i+1][j+1])
return dp[0][0]

动态规划方程(字符串子问题)
text1 = "abcde"
text2 = "ace" 
m = len(text1)
n = len(text2)
dp = [[0]*(n+1) for _ in range(m+1)]
for i in range(1,m+1):
	for j in range(1,n+1):
		if text1[i-1] == text2[j-1]:
			dp[i][j] = 1 + dp[i-1][j-1]
		else:
			dp[i][j] = max(dp[i][j-1],dp[i-1][j])
return dp[m][n]
动态规划方程(二维状态转移,股票买卖例)
dp = [[0,0] for _ in range(len(prices))]
for i in range(1,len(prices)):
	if i == 0:
		dp[i] = [0,-prices[i]]
		continue
	dp[i][0] = max(dp[i-1][0], dp[i-1][1]+prices[i])
	dp[i][1] = max(dp[i-1][1], dp[i-1][0]-prices[i])
return dp[-1][0]
动态规划方程(三维状态转移,股票买卖例)
dp = [[[0,0] for _ in range(3)] for _ in range(len(prices))]
for i in range(0,len(prices)):
	for k in range(2,0,-1):
		if i == 0:
			dp[i][k] = [0, -prices[0]]
			continue
		dp[i][k][0] = max(dp[i-1][k][0], dp[i-1][k][1]+prices[i])
		dp[i][k][1] = max(dp[i-1][k][1], dp[i-1][k-1][0]-prices[i])
return dp[-1][2][0]
动态规划方程(编辑距离)
def minDistance(word1: str, word2: str) -> int:
	nums = [[None for _ in range(len(word2)+1)] for _ in range(len(word1)+1)]
	for i in range(len(word1)+1):
		for j in range(len(word2)+1):
			if i == 0 and j == 0:
				nums[i][j] = 0
 				continue
			if i == 0 and j != 0:
				nums[i][j] = nums[i][j-1]+1
				continue
			if i != 0 and j == 0:
				nums[i][j] = nums[i-1][j]+1
				continue
			if word1[i-1] == word2[j-1]:
				nums[i][j] = nums[i-1][j-1]
			else:
				nums[i][j] = min(nums[i-1][j-1]+1, nums[i-1][j]+1, nums[i][j-1]+1)
	return nums[-1][-1]
Tire树(字典树,前缀树)
class Trie: #使用字典实现
    def __init__(self):
        self.lookup = {}
		self.end_of_word = "#"
		
    def insert(self, word: str) -> None: #插入
        tree = self.lookup
        for ch in word:
            if ch not in tree:
                tree[ch] = {}
            tree = tree[ch]
        tree[self.end_of_word] = self.end_of_word

    def search(self, word: str) -> bool: #搜索
        tree = self.lookup
        for ch in word:
            if ch not in tree:
                return False
            tree = tree[ch]
        if self.end_of_word in tree:
            return True
        return False

    def startsWith(self, prefix: str) -> bool: #是否是插入单词的前缀
        tree = self.lookup
        for ch in prefix:
            if ch not in tree:
                return False
            tree = tree[ch]
        return True
并查集(通常用于解决两两之间、朋友圈类的问题)
class Solution:
    def findCircleNum(self, isConnected: List[List[int]]) -> int:
        n = len(isConnected)
        p = [i for i in range(n)]
        for i in range(n):
            for j in range(n):
                if isConnected[i][j] == 1:
                    self.union(p, i, j)
        return len(set([self.parent(p, i) for i in range(n)]))
    def union(self, p: List[int], i: int, j: int) -> None: 
        p1 = self.parent(p, i)
        p2 = self.parent(p, j)
        p[p1] = p2
    
    def parent(self, p: List[int], i: int) -> int: 
        root = i
        while p[root] != root:
            root = p[root]
        while p[i] != i:
            x = i
            i = p[i]
            p[x] = root
        return root
位运算
#判断奇偶
(x&1)==1 #奇
(x&1)==0 #偶

x = x>>1 #x=x/2,运算更快
X=X&(X-1) #清零最低位的1
X&-X #得到最低位的1
X&~X #得到0

x&(~0<<n) #将x最右边的n位清零
(x>>n)&1 #获取x的第n位的值(0或1)
x&(1<<(n-1)) #获取x第n位的幂值
快速排序
def quickSort(array: List[int], begin: int, end: int):
	if end <= begin:
		return 
            
	counter, pivot = begin, random.randint(begin, end)
	array[pivot], array[end] = array[end], array[pivot]
	for i in range(begin, end):
		if array[i] < array[end]:
			array[i], array[counter] = array[counter], array[i]
			counter += 1
	array[counter], array[end] = array[end], array[counter]

	quickSort(array, begin, counter-1)
	quickSort(array, counter+1, end)
归并排序
def mergeSort(array: List[int], begin: int, end: int):
	if end <= begin:
		return 
	
	mid = (begin+end)>>1
	mergeSort(array, begin, mid)
	mergeSort(array, mid+1, end)

	tmp = []
	i, j = begin, mid+1
	while(i <= mid and j <= end):
		if array[i] <= array[j]:
			tmp.append(array[i])
			i += 1
		else:
			tmp.append(array[j])
			j += 1
	while(i <= mid):
		tmp.append(array[i])
		i += 1
	while(j <= end):
		tmp.append(array[j])
		j += 1
	
	array[begin:end+1] = tmp
堆排序
import heapq   #直接调用堆的包

def heapSort(nums: List[int]):
	heap = []
	for i in range(len(nums)):
		heapq.heappush(heap, nums[i])
	for i in range(len(nums)):
		nums[i] =  heapq.heappop(heap)
	return nums
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值