今天,我们来简单介绍一下深度优先搜索(DFS)的概念和使用。

在百度词条中,对深搜的解释是这样的。

百度词条中的解释

由此,我们可知,深搜是广泛运用到 图 中的搜索方法之一。

用深度优先搜索遍历图的基本思路是:

(1)访问顶点v;

(2)依次从v的未被访问的邻接点出发,对图进行深度优先遍历;直至图中和v有路径相通的顶点都被访问;

(3)若此时图中尚有顶点未被访问,则从一个未被访问的顶点出发,重新进行深度优先遍历,直到图中所有顶点均被访问过为止。 当然,当人们刚刚掌握深度优先搜索的时候常常用它来走迷宫.事实上我们还有别的方法,那就是广度优先搜索(BFS,我们以后在做介绍).

但在今天,为了简化问题,我们不以 图 作为问题来论述 深搜 ,我们用排列组合的思想来运用 深搜。好,我们先来看一道问题。

题目

显而易见,这道题可以使用循环来枚举每一个数字,但是这样需要用带9层循环,并且满足这样的数字还不只一个。如果使用这样的计算方式,会增加大量的时间复杂度(这里的时间复杂度(O)= n^9),给CPU很大的负担,甚至有些计算机系统不允许执行。

这道题也能在第一个数上从123遍历到333,然后计算出后面的第二个数,第三个数,然后再从中找出不重复的3个3位数,这是一个很好的方法,但是,这跟人用计算器来计算结果有什么区别?我们是要使用计算机从根本来解决这个问题。(这两种方法会在后面提供C\C++和JAVA的代码)

在这里,我们重点讲述更为合理的深度优先搜索方法。这里需要用到 排列组合 的思想,我们先来解释3个数的排列组合,再来类比题目中的9个数的排列组合。

3个数的排列组合

这里我们假设有3个盒子,分别标记上1号,2号,3号。我们现在需要把1、2和3,这三个数字放在其中,有多少种放法呢?这个很简单,即便是没有学过排列组合都能计算出多少种放法。我们先来枚举出组成的3位数吧,有123、132、213、231、321、312,共6种放法。然而,我们只需要运算 3*2*1 ,就能得到有6种放法,但是计算机应该怎么去计算呢?

这里,我们请一个叫小曦的同学帮忙,让他模拟计算机运行,我们给他规定好方法。

首先,小曦手中有3张标着有1、2、和3的卡片,面前有如上图所示的盒子。我们让小曦先去1号盒放一张卡片,再让小曦走到下一个盒子,也就是2号盒放一张卡片,最后到3号盒子放最后一张,即便是后面还有盒子,但小曦手中没有卡片了,也是无法去放的。

现在,我们让小曦开始去放卡片,小曦来到1号盒子前,果断的放了标有1的卡片,然后来到2号盒子前,放了标有2的卡片,最后,小曦只能在第3号盒子放进标有3的卡片。这样,就形成了一个3位数的数字——123。我们记录下这个数字,让小曦收回放在盒子的卡片,这个时候,小曦正好在3号盒子前,所以小曦拿起了3号盒子中的标有3的卡片,然后退回到紧挨着3号盒子的2号盒子,拿起了2号盒子中标记着数字2的卡片,这时候,小曦的手中拿着有标记着2、3数字的两张卡片,小曦发现,手中的数字3卡片还没有放在过盒子2号中,于是小曦将手中的数字3卡片放在2号盒子中,然后来到3号盒子前,只能把数字2的卡片放在3号盒子中。这时,就形成了第二个3位数——132。我们再将132记录好。让小曦收回卡片,小曦按照原来的方法,走回2号盒子前收回数字3卡片后,发现2、3都已经放在盒子里面过了,于是小曦只好退回到1号盒子前收回数字1的卡片,然后发现1号盒子里面还未放过数字2、3的卡片,于是放进了数字2的卡片。(类似于栈一样,后进先出)

就这样,小曦一直重复着这一过程,最终得到123、132、213、231、321、312,6种的放法。我们把图放上来,方便大家理解。

开始

第一步

第二步

第三步,记录数字123

第四步

第五步

第六步

第七步,记录数字132

后面图略。。。

现在,我们按照题中的要求,把3个数扩展到9个数。

9个数的排列组合

还是按照小曦放3个数字的方法来放9个数字。然后让1、2、3号盒子构成的数字与4、5、6号和7、8、9号盒子构成的数字形成如题所示的方式,这样,1到9的数字不会重复出现。好,我们先把代码搬上来。

实例代码

运行结果

这里,我使用了私有的全局的内部类来保存深度优先搜索算法,供主函数调用,并用static保存全局变量。显然,深搜的核心就是方法(函数)的递归。我们下面来介绍步骤。

初始化与book

这里解释一下,这里构造器构造出指定了长度的数组在没有赋值以前默认为0。C\C++中,全局变量在没有赋值以前也是默认为0。所以这里不需要再初始化为0。我们在这里构造了卡片和盒子,a的下标表示几号盒子,book的下标表示卡片上的数字(类似于桶排序的方法)。

放卡片

这里用了book来标记卡片是否已经放在盒子中,而在book中间的toBeUsed回调,则是往下一个盒子移动。

判断是否放完盒子和判断是否满足条件

调用方法且开始时站在第一个盒子前

到这里基本就已经解决问题,如果还是无法深搜的概念,可以反复理解这段代码。下面,我们提供C\C++的代码。

C\C++示例代码

我们来看第二种方法的C\C++代码,JAVA代码这里省略。(基本一样)

这里使用了指针来读取每一个得到数,并保存在array数组中,每保存一个数的时候,就判断是否存在重复的。

C\C++示例代码

九重循环的枚举方法就在这里省略。

注:mooc上的编译器可能存在问题,不支持复杂的运算。也可能是超时问题(几率很小)。

java dfs_Java数据结构与算法 深搜(DFS)的简单使用(一)之排列组合相关推荐

  1. 深入递归、深搜dfs、回溯、剪纸学习。

    深入递归,深搜dfs,回溯,剪枝 参考于博客 一.双管齐下解递归 "逐步生成结果"类问题之数值型 自下而上的递归(递推,数学归纳,动态规划) 解决简单情况下的问题. 推广到稍复杂情 ...

  2. [二叉树|深搜|dfs] leetcode 404 左叶子之和

    [二叉树|深搜|dfs] leetcode 404 左叶子之和 1.题目 题目链接 计算给定二叉树的所有左叶子之和. 示例: 3/ \9 20/ \15 7在这个二叉树中,有两个左叶子,分别是 9 和 ...

  3. 题解HDU6148 Valley Numer(数位DP+深搜DFS)

    题解HDU6148 Valley Numer[数位DP+深搜DFS] 题目 解析 参考源码 题目 Description: 众所周知,度度熊非常喜欢数字. 它最近发明了一种新的数字:Valley Nu ...

  4. 2412 - 和为K ---深搜dfs剪枝

    **2412 - 和为K ---深搜dfs优化 **来源:东方博宜oj oj.czos.cn #include<bits/stdc++.h> using namespace std; co ...

  5. acwing-167. 木棒(深搜dfs+减枝)

    乔治拿来一组等长的木棒,将它们随机地砍断,使得每一节木棍的长度都不超过 50 个长度单位. 然后他又想把这些木棍恢复到为裁截前的状态,但忘记了初始时有多少木棒以及木棒的初始长度. 请你设计一个程序,帮 ...

  6. 基于java的数据结构学习——数组实现的栈以及简单应用C++实现

    基于java的数据结构学习--数组实现的栈以及简单应用的 C++ 实现 源码: // // Created by PC-Saw on 2019/1/3. //#ifndef DATA_STRUCTUR ...

  7. 算法学习笔记(六) 二叉树和图遍历—深搜 DFS 与广搜 BFS

    图的深搜与广搜 复习下二叉树.图的深搜与广搜. 从图的遍历说起.图的遍历方法有两种:深度优先遍历(Depth First Search), 广度优先遍历(Breadth First Search),其 ...

  8. 算法——广搜(BFS)/深搜(DFS)

        在图的基本算法中,最初接触的就是图的遍历算法,根据访问节点的顺序,可分为广度优先搜索(BFS)和深度优先搜索(DFS). 广度优先搜索 广度优先搜索算法主要解决两个问题: 从节点A出发有到节点 ...

  9. 数据结构与算法—图论之dfs、bfs(深度优先搜索、宽度优先搜索)

    文章目录 前言 邻接矩阵和邻接表 深度优先搜索(dfs) 宽度(广度)优先搜索(bfs) 总结与比较 前言 在有向图和无向图中,如果节点之间无权值或者权值相等,那么dfs和bfs时常出现在日常算法中. ...

最新文章

  1. nginx+lua 配置302 不改写白名单哈希表
  2. Java语言基础(数组)
  3. 终于快忙出头了,开了个FTP给大家用[mikespook]
  4. Cage验证码生成器快速上手
  5. Opencv——查找并绘制凸包、凸包与轮廓的关系
  6. Gratipay如何帮助解决“搭便车”问题
  7. ASP.NET 前端Ajax获取数据并刷新
  8. Snort规则检测引擎--架构解析
  9. 使用基于JSON的实体在C#中缓存远程数据
  10. iview 远程搜索选择器方法使用,选择之后清空选择的项
  11. java.lang.IllegalStateException: ActionBarImpl can only be used with a compatible window decor layou
  12. 自学python3 最好的入门书籍-学习python3入门书籍选哪些?
  13. win7右下角无线网图标显示未连接,但是实际上已连接上,也能上网
  14. 编程软件哪个比较好用?
  15. Android 系统签名实现的三种方式
  16. WIN10_用户获取最高的管理员权限(关闭UAC控制)
  17. Vue2.0 响应式原理 通俗易懂
  18. CVPR 2020 之文本检测识别论文大盘点
  19. 超大背包问题(01背包)
  20. 如何下载BiliBili视频

热门文章

  1. RT-Thread中堆和栈内存的分配
  2. airpodspro窃听模式_AirPods Pro实时收听怎么关闭? AirPods Pro实时收听的使用方法
  3. android android 修改 jpg exif 属性,Android开发之使用ExifInterface获取拍照后的图片属性...
  4. fpga摄像头模块_FPGA开源项目:双目测距(一)之双目图像采集显示以及图片保存...
  5. 新手学java7编程_新手学Java 7编程:面向对象程序设计
  6. 用Crossdev安装MIPS交叉编译工具链
  7. 解决6410 WINCE6 应用层调用SetSystemPowerState api关机无效的问题
  8. php获取跳转前的地址,PHP获取短链接跳转后的真实地址和响应头信息的方法
  9. 一步步编写操作系统 35 内存为何要分页
  10. php实现把es6转为es5,如何将ES6代码转化为ES5?