循环、递归、分治、回溯、动态规划

简介: 循环、递归、分治、回溯、动态规划

一、循环(重复)


不断的重复、有始有终


循环实现


private loop(){    for(start; end; loop termination){
        expression1;
        expression2;
        expression3;        
    }
}


def loop():
    for start in end/loop_termination:
        expression1;
        expression2;
        expression3;


二、递归


特征:自相似性、有始有终


实现:归去来兮、适可而止


何时想到递归?


子问题与原始问题做同样的事


递归实现:


private void recursion(int level,int param1,int param2...):{    // 终止条件(recursion terminato)
    if(level > MAX_LEVEL){
        # process_rsult        return
    }    // 处理此层过程逻辑(process logic in current level)
     process(level, data1, data2...)    // 进入下一层(dill down)
    recursion(level: level + 1, newParam):    // 如果需要恢复此层状态    }


def recursion(level, param1, param2...):
    # 终止条件(recursion terminato)
    if level > MAX_LEVEL:       # process_rsult
        return
    # 处理此层过程逻辑(process logic in current level)
    process(level, data1, data2...)    # 进入下一层(dill down)
    self.recursion(level + 1, param1, param2...):    # 如果需要恢复此层状态


三、分治


定义:分而治之,群臣归一


何时想到分治?


当复杂的问题可以拆分成简单的子问题


分治实现:


private static int divide_conquer(Problem, Param1, Param2...) {  // 终止条件
  if (problem == NULL) {    int res = process_last_result();    return res;     
  }  // 拆分子问题
  subProblems = split_problem(problem)
  res0 = divide_conquer(subProblems[0])
  res1 = divide_conquer(subProblems[1])
  ... 
  // 合并子问题结果
  result = process_result(res0, res1);  return result;
}


def divide_conquer(Problem, Param1, Param2...):
     # 终止条件
     if problem is None:        return 
     # 拆分子问题
     subproblems = split_problem(problem, data) 
     subresult1 = self.divide_conquer(subproblems[0], p1, ...) 
     subresult2 = self.divide_conquer(subproblems[1], p1, ...) 
     subresult3 = self.divide_conquer(subproblems[2], p1, ...) 
      ...        # 合并子问题结果
     result = process_result(subresult1, subresult2, subresult3, …)


四:回溯


采用“试错”思想,尝试“分步”去解决问题。在分步的过程中。根据上层结果,尝试此层最优解决此问题,如果此层较于上层不是最优则回溯。


五、DP(Dynamic programming) 动态规划/动态递推


自地向上


定义


In both contexts it refers to simplifying a complicated problem by breaking it down into simpler sub-problems in a recursive manner. While some decision problems cannot be taken apart this way, decisions that span several points in time do often break apart recursively.


在这两种情况下,它都是指通过递归的方式将复杂问题分解为更简单的子问题来简化它。虽然有些决策问题不能用这种方式分解,但是跨越多个时间点的决策通常会递归地分解。


Simplifying a complicated problem by breaking it down into simpler sub problem(in a recursibe manner)


把一个复杂的问题分解成更简单的子问题简化它(用一种递归的方式)


自低向上


以斐波那契数列为例:


F(0) = 0, F(1) = 1 
F(N) =  F(N - 1) + F(N - 2)(N >= 2)


递归(傻递归):


若计算F(4);需计算


lin1 F(4) = f(3)、f(2), 
lin2 F(3):f(2)、f(1), F(2) = f(1) + f(0)


DP:


i(0) = 0, i(1) = 1
[0, 1, 1, 2, 3, 5]


总结


动态规划、递归、分治、无本质区别


共性: 重复子问题


异性:最优子结构、中途淘汰次优

目录
相关文章
算法:分治思想处理归并递归问题
算法:分治思想处理归并递归问题
|
6月前
|
算法
递归回溯解决迷宫问题
递归回溯解决迷宫问题
41 4
|
6月前
|
Java Python
汉诺塔递归问题,递归思路详解
汉诺塔递归问题,递归思路详解
93 0
|
6月前
|
算法 JavaScript
算法(分治、贪心、dp、回溯、分支限界)总结
算法(分治、贪心、dp、回溯、分支限界)总结
递归的思路
今天给老铁们回顾一下递归的思路以及方法,也是给自己的一个归纳总结。
117 0
递归的思路
|
算法 JavaScript Java
数据结构与算法-暴力递归与回溯
数据结构与算法-暴力递归与回溯
183 0
数据结构与算法-暴力递归与回溯
|
机器学习/深度学习 缓存 机器人
从暴力递归到动态规划,记忆化搜索
从暴力递归到动态规划,记忆化搜索
从暴力递归到动态规划,记忆化搜索
|
算法
递归+回溯求解数独问题
导读:回溯是常用的算法理论之一,很多规模较大、直接分析较为复杂的问题都可以考虑用回溯求解,例如N皇后问题、骑士周游和走迷宫问题等。本质上,回溯问题是一种优化后的暴力求解,通过及时的剪枝和启发式的寻找最优路径,可以有效加速求解过程。回溯还常常与递归搭配使用
162 0
递归+回溯求解数独问题
二叉树的遍历(递归、迭代和morris多解法)
二叉树的遍历(递归、迭代和morris多解法)
|
算法 容器
递归树:借助树来求解递归算法时间复杂度
递归树与时间复杂度分析 我们前面讲过,递归的思想就是,将大问题分解为小问题来求解,然后再将小问题分解为小小问题。这样一层一层地分解,直到问题的数据规模被分解得足够小,不用继续递归分解为止。 如果我们把这个一层一层的分解过程画成图,它其实就是一棵树。我们给这棵树起一个名字,叫作递归树。我这里画了一棵斐波那契数列的递归树,你可以看看。节点里的数字表示数据的规模,一个节点的求解可以分解为左右子节点两个问题的求解。
268 0
递归树:借助树来求解递归算法时间复杂度