算法笔试题:回溯法解题

4 篇文章 0 订阅

回溯法

1.概念和思想

回溯法:全称为探索与回溯法

  • 概念:一种选优搜索法,又称试探法,按照选优条件进行向前搜索来达到目的。但是当探索到某一步时,发现现在进行的条件并不是最优解或者无法达到预期,就退回上一步重新选择,这种走不通就退回再走的技术就是回溯法
  • 注:满足回溯条件的某个状态的某个点称为回溯点
  • 回溯法有“通用的解题”的美称,可以系统性的搜索一个问题的所有解或任一解,采用的是深度优先策略
  • 回溯法的结构就像是一个多叉树,是部分解的状态集合,每一个分叉的结点都是这个问题可能的部分解,它的儿子就是在这些分叉的基础上生成的部分解,树的根就是问题的初始状态,所以这中集合状态也叫状态空间树

2.解题步骤与方法

解题步骤

确定了问题的解空间结构后,回溯法将从开始结点(根结点)出发,以深度优先的方式搜索整个解空间。开始结点成为活结点,同时也成为扩展结点。在当前的扩展结点处,向纵深方向搜索并移至一个新结点,这个新结点就成为一个新的活结点,并成为当前的扩展结点。如果在当前的扩展结点处不能再向纵深方向移动,则当前的扩展结点就成为死结点。此时应往回移动(回溯)至最近的一个活结点处,并使其成为当前的扩展结点。回溯法以上述工作方式递归地在解空间中搜索,直至找到所要求的解或解空间中已无活结点时为止。
运用回溯法解题的关键要素有以下三点:
(1) 针对给定的问题,定义问题的解空间;
(2) 确定易于搜索的解空间结构;
(3) 以深度优先方式搜索解空间,并且在搜索过程中用剪枝函数避免无效搜索
如之前的迷宫的迷宫问题,可以利用这三个步骤来进行解决

解题方法

  • 通常采用的解题方法有两种:递归法和递推法

递归法:

递归法就如同两面对着的镜子,在镜子里看到的会是一个嵌套一个的镜子,在程序中也不例外
思路简单,设计容易,浪费时间与空间导致效率很低,在笔试过程中可能无法通过编译
但是递归也是我们常用到的解题方式,我们熟知的斐波那契数列,就经常用递归来实现
//python方式:
def fib_recur(n):
  assert n >= 0, "n > 0"
  if n <= 1:
    return n
  return fib_recur(n-1) + fib_recur(n-2)
//C++方式:
void fib_recur(int n){
	if (n <= 1)
        return n;
    else
        return fun(n-1) + fun(n-2);
}

递推法:
算法设计相对复杂,但效率高
例如:用递推法实现斐波那契数列

//Python:
def fib_loop(n):
  a, b = 0, 1 //a=0,b=1
  for i in range(n+1):
    a, b = b, a + b //a=b ,b=a+b
    return a
//C++方式:
int fib_recur(int n){
	int f0 = 1, f1 = 1;
    int f2 = 0; 
    for(int i = 3; i <= n; i++){
            f2 = f0 + f1;
            f0 = f1;
            f1 = f2;
        }
        return f2;
        }

常见问题

  1. 装载问题
  2. 0-1背包问题
  3. 旅行售货员问题
  4. 八皇后问题
  5. 迷宫问题:代码见上一章博客
  6. 图的m着色问题

如背包问题和装载问题,通常会先选择贪心算法,先选择符合要求的做为状态集合,然后进行深度优先搜索
如旅行售货员问题,一个售货员把几个城市旅行一遍,要求走的路程最小。它的解就是几个城市的排列,解空间就是排列树。

有关回溯法常见问题代码:
参考链接:http://blog.csdn.net/jarvischu

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值