5 递归 分治 回溯 贪心算法 二分查找 动态规划

关键:寻找重复子问题

递归

#python
def recursion(level, param1,param2,...):
	#recursion terminator
	if level > MAX_LEVEL:
		process_result
		return
	#process logic in current level
	process(level, data...)
	#drill down
	self.recursion(level + 1,p1,...)
	#reverse the current level status if needed
//java
public void recur(int level, int param){
	//terminator
	if(level > MAX_LEVEL){
	//process result
	return;
	}
	//process current logic
	process(level,param);
	//drill down
	recur(level:level+1,newParam);
	//restore current status
	

分治

divide&conquer

#分治代码模板
def divide_conquer(problem,param1,param2,...):
	#recursion terminator
	if problem is None:
		print_result
		return
	#prepare data
	data = prepare_data(problem)
	wubproblems = split_problem(problem,data)
	#conquer subproblems
	subresult1 = self.divide_conquer(subproblems[0],p1,...)
	subresult2=self.divide_conquer(subproblems[1],p1,...)
	subresult3=self.divide_conquer(subproblems[2],p1,...)
	...
	#process and generate the final result
	result = process_result(subresult1,subresult2,subresult3...)
	#revert thr current level states

在这里插入图片描述
在这里插入图片描述

回溯

Backtracking
思想是试错
回溯法通常用最简单的递归方法来实现,在反复重复上述的步骤后可能出现两种情况:

• 找到一个可能存在的正确的答案;

• 在尝试了所有可能的分步方法后宣告该问题没有答案。

在最坏的情况下,回溯法会导致一次复杂度为指数时间的计算。

DFS BFS

结点

#python
class TreeNode:
	def __init__(self,val):
		sef.val = val
		self.left,self.right = None,None
//java
public class TreeNode{
	public int val;
	public TreeNode left,right;
	public TreeNode(int val){
		this.val = val;
		this.left = null;
		this.right = null;
	}
	}
dfs递归
visited = set()
def dfs(node,visited):
	if node in visited:#terminator
		#already visited
		return
	visited.add(node)
	#process current node here
	for next_node in node.children():
		if not next_node in visited:
			dfs(next_node,visited)
	

在这里插入图片描述

dfs非递归
def DFS(self,tree):
	if tree.root id None:
		return []
	visited,stack=[],[tree,root]
	while stack:
		node = stack.pop()
		visited.add(node)
		process(node)
		nodes = generate_related_nodes(node)
		stack.push(nodes)
bfs代码
def bfs(graph ,start,end):
	queue =[]
	queue.append([start])
	visited.add(start)

	while queue:
	node = queue.pop()
	visited.add(node)
	
	process(node)
	nodes = generate_related_nodes(node)
	queue.push(nodes)
	

在这里插入图片描述

贪心算法

Greedy
问题能够分解成子问题来解决,子问题的最优解能递推到最终问题的最优解。这种子问题最优解称为最优子结构。

每一步选择重都采取在当前状态下最好的选择。

贪心算法与动态规划的不同在于它对每个子问题的解决方案都做出选择,不能回退。动态规划则会保存以前的运算结果,并根据以前的结果对当前进行选择,有回退功能。

动态规划 和 递归或者分治 没有根本上的区别(关键看有无最优的子结构)
拥有共性:找到重复子问题

差异性:最优子结构、中途可以淘汰次优解

二分查找

目标函数单调
存在上下界(bounded)
能够通过索引访问(index accessible)

left ,right = 0,len(array)-1
while left <= right:
	mid = (left +right)/2
	if array[mid] == target:
		#find the target!!
		break or return result
	elif array[mid]<target:
		left = mid+1
	else:
		right = mid -1

在这里插入图片描述
在这里插入图片描述

动态规划

状态转移方程(DP方程)

关键点:

  1. 最优子结构 opt[n] = best_of(opt[n-1], opt[n-2], …)

  2. 储存中间状态:opt[i]

  3. 递推公式(状态转移方程或者 DP 方程)
    Fib: opt[i] = opt[n-1] + opt[n-2]
    二维路径:opt[i,j] = opt[i+1][j] + opt[i][j+1] (且判断a[i,j]是否空地)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值