小白也能看懂的 DFS 算法本质详解

本文深入浅出地介绍了DFS(深度优先搜索)算法的本质,通过生动的例子解释了无目的和有目的的DFS,并探讨了如何在实际问题中高效地应用DFS。文章强调了递归和状态保存在DFS中的关键作用,同时提供了不同类型的DFS问题的递归深度分析,帮助读者更好地理解和应用DFS算法。
摘要由CSDN通过智能技术生成

DFS算法的本质

引言

DFS 俗称深搜,是一种常见的算法模型

我们通过借助函数递归递归停止条件的运用实现对数据的高级枚举

对于DFS算法而言,最重要的是如何去枚举数据,即如何去搜索?

这是在运用DFS之前我们就应该思考的问题,只有对其思考清楚,才不妨碍我们下一步去运用代码实现DFS!

OK! 让我们开始吧!


何为搜索?

让我们先忘记你学过DFS算法这件事,抛开脑子中具体的代码结构,单纯地以一个自然人地角度去思考,什么是搜索?

单独思考一个词汇可能我们不会获得很多,下面我们借助具体例子来说明:

假如我说——我们去搜索一间房子,你会想到什么?

寻找?探索?还是在房子里面转悠?

可能这么说会引起歧义,这里我们再具体一点

换成——我们去搜索这间房子,看看有没有宝藏藏在里面!

上面两句话地区别在于,一个无目的,一个有目的

一个只是再房间里面转悠,一个在转悠地同时还要看看房间里面有没有宝藏

其实上面这两句话对应了DFS算法的两种基本类型

无目的的深度搜索——裸的DFS
有目的的深度搜索——一般的DFS

(1)无目的DFS就像你去亲戚家做客,主人带你在他家闲逛了解他家的布局

(2)有目的DFS就像土匪掠夺财产时在你家到处探寻,直到找到你的私人小金库

但作为 算法 而言我们不能到处瞎转悠,有经验的主人和土匪往往也不会那么做!

我们需要一种高效的搜索方案,它能让我们在最短时间内完成搜索任务!


如何搜索?

DFS的关键要领在于——当下这一步干什么,然后下一步干什么。

这是所有DFS搜索🔍算法的核心,我们只要知道当下和下一步的动作,就能通过递归连贯出整个搜索动作。

让我们来举个例子
题目:DFS - 选数
题目大意:求从N个数里面选出K个数出来并且使选出的数的和为素数的的可能性有几种?

假如:N=5,K=3

5个数为:1 2 3 4 5

我们要做的是挑出3个数出来然后计算求和并判断和是否为素数。

你可能已经想到怎么去选了,一般的选法如下:

1 2 3
1 2 4
1 2 5
1 3 4
1 3 5
1 4 5
2 3 4

我们要做的就是每一次选出一个数,首先仔细观察上述选数过程
当我们去选1 2 3时我们发现这是依次递增的,我们不免想到用For循环去实现这个选数过程,For循环每进行一次选入一个数
可能你会这么写:

dfs(int i,int k,int n)//选入的数为i,选了k个数,要选n个数
{
   
	if(k==n)
	//略
	for(int i=1;i<=n;i++)
	dfs(i+1,k+1,n)
	//略
}

但问题来了我们在1 2 3选完之后是如何蹦到1 2 4呢?

难不成我们需要再从头选一遍,标记3已经被选过了,直接越过它去选4

仔细思考你会发现这是一个无比繁琐的工作,你需要灵活的标记策略来应对不同的选数情况

我们想要的是不再从头去选,而是在选完1 2的基础上再去直接选4

所以我们需要一种方法来保留选完1 2时的状态

可能DFS算法尚在研究<

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值