搜索算法1——聊聊dfs与回溯

目录

1.dfs 的概念

$\ \ \ $1.1 dfs 的概念

2.dfs 的做法

$\ \ \ $2.1 为什么要用 dfs

$\ \ \ $2.2 dfs 如何实现

$\ \ \ $2.3 复杂度分析

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与回溯的更多相关文章

  1. 洛谷1378 油滴扩展 dfs进行回溯搜索

    题目链接:https://www.luogu.com.cn/problem/P1378 题目中给出矩形的长宽和一些点,可以在每个点放油滴,油滴会扩展,直到触碰到矩形的周边或者其他油滴的边缘,求出剩余面 ...

  2. POJ 3050 Hopscotch【DFS带回溯】

    POJ 3050 题意: 1.5*5的方阵中,随意挑一格,记住这个格子的数字 2.可以上下左右走,走5次,每走一次记录下所走格子的数字 3.经过以上步骤,把所得6个数字连起来,形成一串数字.求共可以形 ...

  3. 搜索(BFS、DFS、回溯)

    这类题是最简单的了都是一个套路,不像动态规划一类题一个套路,没做过就是不会也极难想出来. 一.BFS 解决的问题:用来初始点解决到指定点的最短路径问题,因为图的每一层上的点到初始点的距离相同.(注意是 ...

  4. leetcode 357. 计算各个位数不同的数字个数(DFS,回溯,数学)

    题目链接 357. 计算各个位数不同的数字个数 题意: 给定一个非负整数 n,计算各位数字都不同的数字 x 的个数,其中 0 ≤ x < 10n . 示例: 输入: 2 输出: 91 解释: 答 ...

  5. 【每日一题】【DFS和回溯的区别】【BFS】104. 二叉树的最大深度-211227/220218

    给定一个二叉树,找出其最大深度. 二叉树的深度为根节点到最远叶子节点的最长路径上的节点数. 说明: 叶子节点是指没有子节点的节点. 示例:给定二叉树 [3,9,20,null,null,15,7], ...

  6. 深搜(DFS),回溯,Fire Net

    题目链接:http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemId=2 解题报告: 这里的深搜有一点不同,就是,在深搜每一个点时,都要深搜每 ...

  7. leetcode 473. 火柴拼正方形(DFS,回溯)

    题目链接 473. 火柴拼正方形 题意 给定一串数,判断这串数字能不能拼接成为正方形 思路 DFS,但是不能每次从从序列开始往下搜索,因为这样无法做到四个边覆盖不同位置的值,比如输入是(5,5,5,5 ...

  8. [leetcode] 37. 解数独(Java)(dfs,递归,回溯)

    37. 解数独 1A 这个题其实15分钟左右就敲出来并且对了...但是由于我输错了一个数..导致我白白debug一个多小时.. 没啥难度,练递归-dfs的好题 class Solution { pri ...

  9. BFS DFS与回溯

    https://blog.csdn.net/u014303647/article/details/88328526 cyc: https://github.com/CyC2018/CS-Notes/b ...

  10. 多校HDU5723 最小生成树+dfs回溯

    Abandoned country Time Limit: 8000/4000 MS (Java/Others)    Memory Limit: 65536/65536 K (Java/Others ...

随机推荐

  1. langchain-知识库问答

    本地接入 百川 langchain调用 参考:https://github.com/datawhalechina/self-llm/blob/master/BaiChuan/03-Baichuan2- ...

  2. ESP32 VScode环境问题

    vsdcode esp-idf插件安装 报错: Espressif\tools\idf-python\3.11.2\python.exe -m pip" is not valid. (ERR ...

  3. 一种基于alpine、支持ARM架构64位的镜像构建方法及其构建系统

    本文分享自天翼云开发者社区<一种基于alpine.支持ARM架构64位的镜像构建方法及其构建系统>,作者:郑****团 一种基于alpine.支持ARM架构64位的镜像构建方法及其构建系统 ...

  4. 取消浏览器中记住密码自动填充时弹出Windows安全中心的验证

    1.问题描述 我们在使用谷歌浏览器的过程中,经常会将一些账号和密码记住在浏览器中,方便下次通过浏览器自动填充. 此方式虽然方便,但是有时候会遇到一种情况,那就是每次在浏览器中使用自动填充的时候,需会弹 ...

  5. 如何在M芯片的Mac上爽玩原神

    [热点速递]苹果震撼发布全新M4 Mac mini,国补福利下惊喜价仅约3500元!这不仅是一次办公体验的全新升级,更是对高效能与性价比完美融合的一次致敬.想象一下,以如此亲民的价格,拥抱苹果标志性的 ...

  6. 让 LLM 来评判 | 评估你的评估结果

    评估你的评估结果 这是 让 LLM 来评判 系列文章的第三篇,敬请关注系列文章: 基础概念 选择 LLM 评估模型 设计你自己的评估 prompt 评估你的评估结果 奖励模型相关内容 技巧与提示 在生 ...

  7. AI 时代 UI 设计的哲学与伦理

    无论是在桌面.移动应用,还是未来可能出现的全新形态中,空间直觉始终是人类在数字世界中导航的根本. 丹尼尔·罗德里格斯 图片来源:维基百科 想象一下,踏入1427年佛罗伦萨圣母玛利亚诺维拉教堂昏暗的光线 ...

  8. 2025牛客寒假算法基础集训营1 (E)

    [!note] 比赛链接 https://ac.nowcoder.com/acm/contest/953231 A.茕茕孑立之影 题目标签 构造 数论 题目大意 找到一个数x,x和长度为n的数组中的数 ...

  9. 什么是极限编程 (XP)?

    极限编程(XP) 是2000 年代初期最广为人知和使用最多的敏捷方法之一.XP 是Kent Beck.Ron Jeffries和Ward Cunningham的创意,基于他们在戴姆勒克莱斯勒的集体经验 ...

  10. Docker 安装详细步骤

    一.安装前的准备 确认系统要求 不同的操作系统对 Docker 的支持有所不同,常见的如 Windows.MacOS 和各种 Linux 发行版. 启用虚拟化(如果需要) 对于某些系统,可能需要在 B ...