搜索算法1——聊聊dfs与回溯
搜索算法1——聊聊dfs与回溯
目录
$\ \ \ $1.1 dfs 的概念
$\ \ \ $2.1 为什么要用 dfs
$\ \ \ $2.2 dfs 如何实现
$\ \ \ $2.3 复杂度分析
$\ \ \ $3.1 回溯法的概念
$\ \ \ $3.2 回溯法的实现
1.dfs的概念
1.1.dfs的概念
dfs,即深度优先搜索,顾名思义,深度优先,就是不撞南墙不回头,它每一次都会尝试向更深的节点走。
在搜索里,dfs 一般指的是递归函数实现的暴力枚举,一般时间复杂度是 \(O(!n)\)。
对于在图论里的 dfs,这一章并不会介绍,有兴趣的可以跳伞 此处待补。
2.dfs的做法
2.1.为什么要用dfs
我们看一道例题:
输入正整数 \(n\),输出由 \(1\) 到 \(n\) 这 \(n\) 个数取出 \(k\) 个 \((1\le n\le 10,1\le k\le n)\) 的所有组合。
如果不用 dfs,那么这题该怎么办呢?
循环呗。
\(k\) 重循环枚举选哪个数,判断重不重复,然后输出即可。
但是这样复杂度太超标了,足足有 \(O(n^k)\),最高有 \(O(10^{10})\)!
那么,就需要 dfs 来解决这个问题了。
2.2.dfs如何实现
我们可以先模拟一个样例:
\(n=4,k=2\)
我们可以发现,用 2.1 中说的算法,过程如下(设第一重循环变量为 \(i\),第二重循环变量为 \(j\)):
i=1,j=1,重复,跳过
i=1,j=2,输出
i=1,j=3,输出
i=1,j=4,输出
i=2,j=1,重复,跳过
i=2,j=2,重复,跳过
i=2,j=3,输出
i=2,j=4,输出
i=3,j=1,重复,跳过
i=3,j=2,重复,跳过
i=3,j=3,重复,跳过
i=3,j=4,输出
i=4,j=1,重复,跳过
i=4,j=2,重复,跳过
i=4,j=3,重复,跳过
i=4,j=4,重复,跳过
其实,我们完全可以不遍历这些重复的,以节约时间。
我们可以把枚举"选哪个数",变成"枚举数"。
比如,我们可以先枚举到 \(1\),然后延伸出两个分支——\(1\) 选和 \(1\) 不选。
然后这两个分支分别往下枚举又能分别延伸出两个分支——\(2\) 选和 \(2\) 不选。
以此类推。
我们就可以画出类似于这样的一张图:

这就是递归树(例子为 \(k=2\))。
那么我们就知道了,我们可以从 \(1\) 开始枚举,枚举到 \(n\),每一个数有两种方案:选或不选,然后如果选了 \(k\) 个数就输出。
但是,选或不选该怎么实现呢?
这就要用到 dfs 了。
dfs 是通过重复调用一个函数来实现的,例如:
void dfs(int dep,int cnt)//dep是当前枚举到的数,cnt是选了几个数
{
if(dep==n+1)
{
if(cnt==k)
{
for(int i=0;i<cnt;i++)
{
printf("%d ",a[i]);//a[i]是记录的选的数的集合
}
}
return;//只枚举到n,此处return是为了不继续枚举
}
a[cnt]=dep;//这里如果选的话,那么后面cnt+1,dep就存在集合里了,就完成了“选”这一操作.反之,如果不选,那么cnt不变,后面枚举到的dep就覆盖了a[cnt],达到不选的效果
dfs(dep+1,cnt+1);//dep选
dfs(dep+1,cnt+1);//dep不选
}
(注释已经很详细了,应该不用再讲了吧)
2.3.复杂度分析
dfs 无剪枝复杂度一般都是 \(O(!n)\) 级别的。
记住就行。
3.回溯法
3.1.回溯法的概念
回溯法的本质就是对于一棵递归树,程序在遍历时,如果发现遇到了边界条件,就可以回去,搜另外的链。
3.2.回溯法的实现
看例题。
输入正整数 \(n\),输出由 \(1\) 到 \(n\) 这 \(n\) 个数 \((n\le 7)\) 的所有排列,每行一个排列,数与数之间有一个空格,两个排列中,第一个数小的优先输出,第一个数相同,比较第二个数,后面以此类推。
对于这一题,如果我们再用上面的方法,就会漏选。
而由于是 \(n\) 个数选 \(n\) 个,所以我们甚至不用 \(cnt\),只记录 \(dep\) 即可。
那么回溯怎么实现呢?
看代码(解析都在注释里):
void dfs(int dep)
{
if(dep==n+1)//就是到达了边界条件,这里直接输出就行
{
for(int i=1;i<=n;i++)
{
printf("%d ",a[i]);
}
cout<<endl;
return;
}
for(int i=1;i<=n;i++)
{
if(!biao[i])//表示i没被选
{
biao[i]=1;//选i
a[dep]=i;
dfs(dep+1);//往下递归
biao[i]=0;//这就是回溯的关键一步,这一行代码目的在于在接着进行for循环时,不能被这一次遍历到的i干扰,否则就会出现n个数选不完的情况
}
}
}
(也不讲了,这个已经很详细了)
好了,那么搜索算法1就结束了,感谢大家的支持,我是_little_Cabbage_,我们搜索算法2再见!
搜索算法1——聊聊dfs与回溯的更多相关文章
- 洛谷1378 油滴扩展 dfs进行回溯搜索
题目链接:https://www.luogu.com.cn/problem/P1378 题目中给出矩形的长宽和一些点,可以在每个点放油滴,油滴会扩展,直到触碰到矩形的周边或者其他油滴的边缘,求出剩余面 ...
- POJ 3050 Hopscotch【DFS带回溯】
POJ 3050 题意: 1.5*5的方阵中,随意挑一格,记住这个格子的数字 2.可以上下左右走,走5次,每走一次记录下所走格子的数字 3.经过以上步骤,把所得6个数字连起来,形成一串数字.求共可以形 ...
- 搜索(BFS、DFS、回溯)
这类题是最简单的了都是一个套路,不像动态规划一类题一个套路,没做过就是不会也极难想出来. 一.BFS 解决的问题:用来初始点解决到指定点的最短路径问题,因为图的每一层上的点到初始点的距离相同.(注意是 ...
- leetcode 357. 计算各个位数不同的数字个数(DFS,回溯,数学)
题目链接 357. 计算各个位数不同的数字个数 题意: 给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n . 示例: 输入: 2 输出: 91 解释: 答 ...
- 【每日一题】【DFS和回溯的区别】【BFS】104. 二叉树的最大深度-211227/220218
给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null,null,15,7], ...
- 深搜(DFS),回溯,Fire Net
题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=2 解题报告: 这里的深搜有一点不同,就是,在深搜每一个点时,都要深搜每 ...
- leetcode 473. 火柴拼正方形(DFS,回溯)
题目链接 473. 火柴拼正方形 题意 给定一串数,判断这串数字能不能拼接成为正方形 思路 DFS,但是不能每次从从序列开始往下搜索,因为这样无法做到四个边覆盖不同位置的值,比如输入是(5,5,5,5 ...
- [leetcode] 37. 解数独(Java)(dfs,递归,回溯)
37. 解数独 1A 这个题其实15分钟左右就敲出来并且对了...但是由于我输错了一个数..导致我白白debug一个多小时.. 没啥难度,练递归-dfs的好题 class Solution { pri ...
- BFS DFS与回溯
https://blog.csdn.net/u014303647/article/details/88328526 cyc: https://github.com/CyC2018/CS-Notes/b ...
- 多校HDU5723 最小生成树+dfs回溯
Abandoned country Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 65536/65536 K (Java/Others ...
随机推荐
- langchain-知识库问答
本地接入 百川 langchain调用 参考:https://github.com/datawhalechina/self-llm/blob/master/BaiChuan/03-Baichuan2- ...
- ESP32 VScode环境问题
vsdcode esp-idf插件安装 报错: Espressif\tools\idf-python\3.11.2\python.exe -m pip" is not valid. (ERR ...
- 一种基于alpine、支持ARM架构64位的镜像构建方法及其构建系统
本文分享自天翼云开发者社区<一种基于alpine.支持ARM架构64位的镜像构建方法及其构建系统>,作者:郑****团 一种基于alpine.支持ARM架构64位的镜像构建方法及其构建系统 ...
- 取消浏览器中记住密码自动填充时弹出Windows安全中心的验证
1.问题描述 我们在使用谷歌浏览器的过程中,经常会将一些账号和密码记住在浏览器中,方便下次通过浏览器自动填充. 此方式虽然方便,但是有时候会遇到一种情况,那就是每次在浏览器中使用自动填充的时候,需会弹 ...
- 如何在M芯片的Mac上爽玩原神
[热点速递]苹果震撼发布全新M4 Mac mini,国补福利下惊喜价仅约3500元!这不仅是一次办公体验的全新升级,更是对高效能与性价比完美融合的一次致敬.想象一下,以如此亲民的价格,拥抱苹果标志性的 ...
- 让 LLM 来评判 | 评估你的评估结果
评估你的评估结果 这是 让 LLM 来评判 系列文章的第三篇,敬请关注系列文章: 基础概念 选择 LLM 评估模型 设计你自己的评估 prompt 评估你的评估结果 奖励模型相关内容 技巧与提示 在生 ...
- AI 时代 UI 设计的哲学与伦理
无论是在桌面.移动应用,还是未来可能出现的全新形态中,空间直觉始终是人类在数字世界中导航的根本. 丹尼尔·罗德里格斯 图片来源:维基百科 想象一下,踏入1427年佛罗伦萨圣母玛利亚诺维拉教堂昏暗的光线 ...
- 2025牛客寒假算法基础集训营1 (E)
[!note] 比赛链接 https://ac.nowcoder.com/acm/contest/953231 A.茕茕孑立之影 题目标签 构造 数论 题目大意 找到一个数x,x和长度为n的数组中的数 ...
- 什么是极限编程 (XP)?
极限编程(XP) 是2000 年代初期最广为人知和使用最多的敏捷方法之一.XP 是Kent Beck.Ron Jeffries和Ward Cunningham的创意,基于他们在戴姆勒克莱斯勒的集体经验 ...
- Docker 安装详细步骤
一.安装前的准备 确认系统要求 不同的操作系统对 Docker 的支持有所不同,常见的如 Windows.MacOS 和各种 Linux 发行版. 启用虚拟化(如果需要) 对于某些系统,可能需要在 B ...