如果你使用的是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