码迷,mamicode.com
首页 > 其他好文 > 详细

回溯、递归、DFS方法

时间:2020-03-15 00:06:04      阅读:53      评论:0      收藏:0      [点我收藏+]

标签:eve   判断   str   letter   tac   res   深度   形式   全局   

转自:https://www.cnblogs.com/steven_oyj/archive/2010/05/22/1741376.html1.

1.回溯解法框架

我觉得这个递归方法更好理解,迭代的方法我没太看懂。

   1: int a[n];
   2: try(int i)
   3: {
   4:     if(i>n)
   5:        输出结果;
   6:      else
   7:     {
   8:        for(j = 下界; j <= 上界; j=j+1)  // 枚举i所有可能的路径
   9:        {
  10:            if(fun(j))                 // 满足限界函数和约束条件
  11:              {
  12:                 a[i] = j;
  13:               ...                         // 其他操作
  14:                 try(i+1);
  15:               回溯前的清理工作(如a[i]置空值等);
  16:               }
  17:          }
  18:      }
  19: }

以非常典型的,leetcode22题,生成括号为例:

class Solution(object):
    def generateParenthesis(self, N):
        ans = []
        def backtrack(S = ‘‘, left = 0, right = 0):
            if len(S) == 2 * N: #给出解空间
                ans.append(S)
                return
            if left < N:#这两个if判断都是剪枝
                backtrack(S+(, left+1, right) #扩展搜索节点
            if right < left:#这里是关键
                backtrack(S+), left, right+1)

        backtrack()
        return ans

    (1)针对所给问题,确定问题的解空间:

            首先应明确定义问题的解空间,问题的解空间应至少包含问题的一个(最优)解。 (对应if判断解)

    (2)确定结点的扩展搜索规则    (确定往下搜索调用)

    (3)以深度优先方式搜索解空间,并在搜索过程中用剪枝函数避免无效搜索。(if判断递归调用条件)

https://leetcode.com/articles/letter-combinations-of-a-phone-number/ 就像这道题,它只是一个简单的深度优先遍历然后得到所有的解,我觉得它关键是没有剪枝和回去的过程,只是遍历到最深的节点,然后返回了。

2.DFS和回溯的关系

https://www.1point3acres.com/bbs/thread-137584-1-1.html这个讲的挺好的。

特点:就是recursive call之后要退回到之前的一个状态。

回溯是DFS的一种,是它的子集。

技术图片

 

回溯不保留树结构,也就是剪枝的意思。 

定义:https://stackoverflow.com/questions/1294720/whats-the-difference-between-backtracking-and-depth-first-search

回溯是一种更通用的算法。

深度优先搜索是与搜索树结构相关的回溯的一种特定形式。

3.递归和回溯

https://blog.csdn.net/fengchi863/article/details/80086915 这个补充的也挺好的。

  • 递归是一种算法结构,回溯是一种算法思想。
  • 一个递归就是在函数中调用函数本身来解决问题。
  • 回溯就是通过不同的尝试来生成问题的解,有点类似于穷举,但是和穷举不同的是回溯会“剪枝”。

递归的一般过程:

void f()  
{  
     if(符合边界条件)  
     {  
        ///////  
        return;  
     }  

     //某种形式的调用  
     f();  
}  

回溯的一般过程:

void DFS(int 当前状态)  
{  
      if(当前状态为边界状态)  
      {  
        记录或输出  
        return;  
      }  
      for(i=0;i<n;i++)       //横向遍历解答树所有子节点  
      {  
           //扩展出一个子状态。  
           修改了全局变量  
           if(子状态满足约束条件)  
            {  
              dfs(子状态)  
           }  
            恢复全局变量//回溯部分  
      }  
}  

BFS和DFS相似。BFS显式用队列,DFS隐式用栈,即递归。

 

回溯、递归、DFS方法

标签:eve   判断   str   letter   tac   res   深度   形式   全局   

原文地址:https://www.cnblogs.com/BlueBlueSea/p/12494908.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!