0
点赞
收藏
分享

微信扫一扫

算法总结(python3)

登高且赋 2022-02-11 阅读 84
算法python

数组

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

递归

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
举报

相关推荐

0 条评论