关键:能不能将原本的问题分解为更小的子问题
适用于:
回溯模板
res=[]
path=[]
def dfs(start,path,num,res):
#start-初始位置,path-搜索路径,num-原数组,res-最终结果
if 结束条件
res.append(path[:])
return
for i in range(len(num)):
path.append(num[i])
dfs(i+1,path,num,res)
path.pop()
适用于:树或图的遍历
原理:从初始点开始,一直沿着同一个分支遍历,直到该分支结束,然后回溯到上一级继续沿着另一个分支走到底,如此往复,直到所有的节点都有被访问到。
def traversal(self,root,res):
if root==None:
return;
res.append(root.val)
self.traversal(root.left,res)
self.traversal(root.right,res)
用到了双头队列deque,先进先出
from collections import deque
que=deque([root])
while que:
size=len(que)
tmp_res=[]
#当前层遍历
for _ in range(size):
cur=que.popleft()
tmp_res.append(cur.val)
if cur.left:
que.append(cur.left)
if cur.right:
que.append(cur.right)
适用于:统计频率、快速检验某个元素是否出现过等
原理:根据关键码(key)直接访问值(value)的一种数据结构,只要知道key,可以在O(1)时间内查到value。
基本思想:将待求解的问题分解成若干个相互联系的子问题,先求解子问题,然后从这些子问题的解得到原问题的解;对于重复出现的子问题,只在第一次遇到的时候对它进行求解,并把答案保存起来,当再次遇到时,直接引用答案,不必重新求解。
思想:先局部最优解,再把这些局部最优解结合后,得到整体最优解。
“分”: 将一个大而复杂的问题划分成多个性质相同但是规模更小的子问题,子问题继续按照这样划分,直到问题可以被轻易解决.
“治”:将子问题单独进行处理
“合”:将子问题的解进行合并得到原问题的解,因此经常用递归来实现。