当前位置:   article > 正文

关于DFS的一些个人理解_为什么想不明白dfs

为什么想不明白dfs

关于DFS和回溯的讲解

DFS及深度优先搜索,是一种常见的算法策略,这一方法主要是利用递归的形式去解决大量需要遍历for循环的问题,可以提高代码的非‘屎山’性(没有人会因为想枚举写100个循环结构吧)。

DFS是深度优先搜索(废话),他是深度为优先(还是废话),及尽可能一条路走到底,不行再回退,(终于不是废话了)本质上就是暴力枚举。

(说这么多没用的,读者也看不懂,上例题),最常见的一道题,LEETCODE 216,这个就是一道深度优先搜索的经典题目。

那么首先,最直接的思路,就是去for循环,不停的for循化,k是几,就循环几次,那么,这样子程序是不是没有办法写,那么,就是要使用深度优先搜索。

源代码如下。

这里就是一个深度优先搜索的案例,但是,他确实太复杂了,小白看不懂,那么就是一个简单的源代码来放出来

如图,这个便是一个简单版,先说这个然后再讲怎么演变到复杂的那个,这里首先用input作为了一个输入端口(自己想办法转为类函数吧),然后定义了一个DFS程序出口,在这之后,出口表示如果depth达到k时,开始检查,那么这里检查有几个要素,1.是数组path里面的和是否为n,若是不为n,则就直接return(停止搜索),还有就是用一个for循环来检验是否为递增,若是递增,则成立,最后print输出对应结果,还有就是下面的for循环(16行),这个是往path数组里面添加数字,每添加完一个就在将depth往下深一层,这样子就可以完成全部的枚举。

但是这虽然枚举完了,但是他要的是不重复的,那么怎么去重呢,其实只要保证是单调递增的就是可以保证不重复,这是就可以改变16行之后的遍历结果,只要每次遍历从上一个数字+1开始遍历就可以了,这时,就完成了一次剪枝,使每一次循环的范围减小了,但是,这样子时间复杂度还是比较高,所以还要在优化,优化的策略就是添加一个参数n,每遍历一次,n就相应的减小i,这样子当n为0时便可以得出一个结果,同时,由于不用在来使用if来判断,sum是进行过一次遍历,所以会使时间变慢,而这样子就不会使时间复杂度变高,于是便可以得出解。

而之后便是LEETCODE 77题,这道题表示的是求出所有的组合,

这道题主要就是回溯,回溯法有一点难的地方就是打标记,怎么打标机就是这道题的难点,那么直接上源代码

这个代码便是使用了回溯去进行搜索,为了打标记,使用了一个vis数组来处理数据,那么就看combine函数内部,首先就是初始化,有了path来记录答案,有了sol来搜集结果,有了vis来记录,之后就是DFS循环,当depth为k时,就将path加入到sol中,之后就是for循环来往path里面加入数字,首先就是一个判断,判断该数字有没有被加入,也就是if判断,若为FALSE,则就不管,之后就是将那个数组改为TruE,并且进入下一层DFS,之后不断进行循环判断,最后在不断退出循环,并且将标记给改为FALSE。

如此,便可以实现一个排列。

接着,下一道题也是一个DFS的题目,分糖果

这道题也是一个DFS的常见题目,那么直接上代码

这里面就是一个算总数ans的算法,m和n表示剩余的糖果数,因为有两种糖,而之后,因为每一个小朋友都有2—5个糖,那么就是i+j为2—5。然后在减去就可以了

下面一个是买瓜,这道题则是DFS的另一种形式,

那么要解决这一道题,方法和之前不太一样,之前是用path数组来处理答案,但是,这道题则是偏向用更为多项分支来做,源代码如下,

这里要其实对于每一个瓜有三条路,便是不买,买一半,买一个,数组的深度在不断的加深而cnt表示切的刀数,weight表示已经储存的瓜的质量,如图所示,对于瓜表中的每一个瓜,都会有使结果加一个和不加的结果,那么这里就可以来从三条路不断进行选择,最后就可以得到结果,结果ans会不断与cnt比较,更新,最后就是检验是否能够成立,若是ans仁为n+1这个比较大的值,n+1是无论切多少刀都不可能成立的点,那么就说明不成立,输出-1

                              

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/小惠珠哦/article/detail/737325
推荐阅读
相关标签
  

闽ICP备14008679号