回溯算法详细讲解(C语言)

回溯算法实际上就是暴力枚举,只不过它有着递归的保护才得以由此美称,很多人也把该算法称作是万能解题法。

现在就让让我们一起走入这个使你头疼的算法吧。

要想讲解清楚这个算法还真不是一件容易的事情,所以能够帮到大家就是最好的事情了,我尽力吧。

只有文字的讲解让人看着想睡觉,我会借助图片进行讲解。

栗子:

给你一个数N,如果将1到N的所有数字以长度为k输出,请编写程序展示所有的组合可能,不能存在重复的组合。

比如:

输入:N=4,k=2.

输出:[[1,2],[1,3],[1,4],[2,3],[2,4],[3,4]]这就是长度为k的所有可能组合

如果是你编写程序函数的话,你会怎么样做呢。当然我相信很多朋友是可以做得出来的,直接两个for循环就可以搞定。这里两层for语句我也来写一下,也是为了下面讲解做好铺垫。

整体代码:(会的朋友直接跳过)

进一步使用图形来分析这一过程:

遍历第一层的第一个作为组合的开始有[1,2],[1,3],[1,4]这三种结果。

 遍历第一层的第二个作为组合的开始有[2,3],[2,4]这两种结果。或许在这里就有朋友疑惑了,为什么第二层遍历不需要遍历1,直接遍历3,4就行了,因为题目不允许。要求是输出组合,而不是排序组合,排序组合的话就需要。因为[1,2],[2,1]就是排序不同的组合。

 遍历第一层的第三个作为组合的开始只有[3,4]这种结果。

  

那么也就全部组合可能都遍历完了。

大家有没有感觉到像树的遍历。组合结果全在叶子结点上。最后只需要遍历叶子结点就可以得到所有组合结果了。其实直接使用递归也是可以完成的,第一次递归就是遍历第一层,第二次递归遍历第二层。递归的次数取决于树的高度。这里大家一定要这样的概念,每一次的递归都是在遍历每一层。

好了,让我们回到回溯算法中去。

回溯算法就是在递归函数下有回溯操作。(不理解没关系,接着看下面的就好)

这道题采用回溯算法来解决函数应该怎么写呢?

解释:其中combinations是存放组合所有结果的数组,path数组时存放单个组合结果的数组

先用图形走一遍过程:

 

首先遍历递归遍历第一层,将1存入到path数组中。然后继续递归,将2存入path数组中,则path=[1,2](在这里多说一嘴,怎么判断递归停止条件,仔细的朋友应该已经知道了,停止条件就是path数组中元素长度等于输入的k时),将path结果组合存入combination整体数组中。即combination[0]=[1,2],递归在这里结束返回上一层递归,但有一个非常非常重要的一步---回溯操作。也就是将path数组中的第二个元素置为空,让path数组变为[1]。接着递归下一个元素,将元素3存入path数组中,得到的path=[1,3]...一直循环下去,直到所有的结果都被找到。

回溯操作过程:

 将path中的2去掉,为了添加入新的元素3。如果不执行回溯操作的话,path数组依然为[1,2],接下来再继续添加新的元素3进来变为[1,2,3],再继续就是[1,2,3,4],所有这就是为什么要回溯的原因。

整体代码:

在最后我也把回溯算法的模板也给大家写一下吧,

 

  • 16
    点赞
  • 56
    收藏
    觉得还不错? 一键收藏
  • 3
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 3
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值