递归模板代码
const recursion = (level, params) => {
// recursion terminator
if (level > MAX_LEVEL) {
process_result
return
}
// process current level
process(level, params)
// drill down
recursion(level + 1, params)
// clean current level status if needed
}
分治(Divide&Conquer)
- 一种特殊的递归
const divide_conquer = (problem, params) => {
// recursion terminator 终止条件
if (problem == null) {
process_result
return
}
// process current problem 拆分及处理子问题(递归函数)
subproblems = split_problem(problem, data)
subresult1 = divide_conquer(subproblem[0], p1)
subresult2 = divide_conquer(subproblem[1], p1)
subresult3 = divide_conquer(subproblem[2], p1)
...
// merge 合并(分治)
result = process_result(subresult1, subresult2, subresult3)
// revert the current level status 恢复当前层状态
}
感触
- 人肉递归低效、很累
- 找到最近最简方法,将其拆解成可重复解决的问题
- 数学归纳法思维(抵制人肉递归的诱惑)
本质:寻找重复性 -> 计算机指令集
动态规划 Dynamic Programming
- Wiki 定义
- “Simplifying a complicated problem by breaking it down into simpler subproblems”(in a recursive manner)
- 将一个复杂问题分解为简单的子问题(用一种递归的方式)
- Divide & Conquer + Optimal substructure
- 分治 + 最优子结构
- 一般而言,动态规划会让你求一个:最优解、或最大值、或求一个最少的方式
- 所以,不需要存所有状态,只需要存最优状态
- 缓存:状态的存储数组
- 在每一步把次优的状态淘汰掉,在这一步只保留最优的状态
关键点
- 动态规划 和 递归或者分治 没有根本的区别(关键看有无最优的子结构)
- 共性:找到重复子问题
- 差异性:最优子结构、中途可以 淘汰 次优解