Java数据结构与算法 深搜(DFS)的简单使用(一)之排列组合

今天,我们来简单介绍一下深度优先搜索(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上的编译器可能存在问题,不支持复杂的运算。也可能是超时问题(几率很小)。

©著作权归作者所有,转载或内容合作请联系作者
  • 序言:七十年代末,一起剥皮案震惊了整个滨河市,随后出现的几起案子,更是在滨河造成了极大的恐慌,老刑警刘岩,带你破解...
    沈念sama阅读 217,907评论 6 506
  • 序言:滨河连续发生了三起死亡事件,死亡现场离奇诡异,居然都是意外死亡,警方通过查阅死者的电脑和手机,发现死者居然都...
    沈念sama阅读 92,987评论 3 395
  • 文/潘晓璐 我一进店门,熙熙楼的掌柜王于贵愁眉苦脸地迎上来,“玉大人,你说我怎么就摊上这事。” “怎么了?”我有些...
    开封第一讲书人阅读 164,298评论 0 354
  • 文/不坏的土叔 我叫张陵,是天一观的道长。 经常有香客问我,道长,这世上最难降的妖魔是什么? 我笑而不...
    开封第一讲书人阅读 58,586评论 1 293
  • 正文 为了忘掉前任,我火速办了婚礼,结果婚礼上,老公的妹妹穿的比我还像新娘。我一直安慰自己,他们只是感情好,可当我...
    茶点故事阅读 67,633评论 6 392
  • 文/花漫 我一把揭开白布。 她就那样静静地躺着,像睡着了一般。 火红的嫁衣衬着肌肤如雪。 梳的纹丝不乱的头发上,一...
    开封第一讲书人阅读 51,488评论 1 302
  • 那天,我揣着相机与录音,去河边找鬼。 笑死,一个胖子当着我的面吹牛,可吹牛的内容都是我干的。 我是一名探鬼主播,决...
    沈念sama阅读 40,275评论 3 418
  • 文/苍兰香墨 我猛地睁开眼,长吁一口气:“原来是场噩梦啊……” “哼!你这毒妇竟也来了?” 一声冷哼从身侧响起,我...
    开封第一讲书人阅读 39,176评论 0 276
  • 序言:老挝万荣一对情侣失踪,失踪者是张志新(化名)和其女友刘颖,没想到半个月后,有当地人在树林里发现了一具尸体,经...
    沈念sama阅读 45,619评论 1 314
  • 正文 独居荒郊野岭守林人离奇死亡,尸身上长有42处带血的脓包…… 初始之章·张勋 以下内容为张勋视角 年9月15日...
    茶点故事阅读 37,819评论 3 336
  • 正文 我和宋清朗相恋三年,在试婚纱的时候发现自己被绿了。 大学时的朋友给我发了我未婚夫和他白月光在一起吃饭的照片。...
    茶点故事阅读 39,932评论 1 348
  • 序言:一个原本活蹦乱跳的男人离奇死亡,死状恐怖,灵堂内的尸体忽然破棺而出,到底是诈尸还是另有隐情,我是刑警宁泽,带...
    沈念sama阅读 35,655评论 5 346
  • 正文 年R本政府宣布,位于F岛的核电站,受9级特大地震影响,放射性物质发生泄漏。R本人自食恶果不足惜,却给世界环境...
    茶点故事阅读 41,265评论 3 329
  • 文/蒙蒙 一、第九天 我趴在偏房一处隐蔽的房顶上张望。 院中可真热闹,春花似锦、人声如沸。这庄子的主人今日做“春日...
    开封第一讲书人阅读 31,871评论 0 22
  • 文/苍兰香墨 我抬头看了看天上的太阳。三九已至,却和暖如春,着一层夹袄步出监牢的瞬间,已是汗流浃背。 一阵脚步声响...
    开封第一讲书人阅读 32,994评论 1 269
  • 我被黑心中介骗来泰国打工, 没想到刚下飞机就差点儿被人妖公主榨干…… 1. 我叫王不留,地道东北人。 一个月前我还...
    沈念sama阅读 48,095评论 3 370
  • 正文 我出身青楼,却偏偏与公主长得像,于是被迫代替她去往敌国和亲。 传闻我的和亲对象是个残疾皇子,可洞房花烛夜当晚...
    茶点故事阅读 44,884评论 2 354

推荐阅读更多精彩内容

  • 第5篇 宝宝真的是在不知不觉中长大.答应给她买她要的那款零食,她说:妈妈,你下班回来,我和你一起去买吧,你不懂,买...
    小莲蓬儿阅读 181评论 0 0
  • 据说好像是用了射线,
    normidar阅读 767评论 0 1
  • 老子说:道生一,一生二,二生三,三生万物。 王国维说:人有三重境界。第一重境界是看山是山看水是水。第二重境界是看山...
    拂晓起舞阅读 251评论 0 0
  • Growing:准时到了晨晚读地点,复习了中英文与自我介绍这两篇文章。一二节商务英语阅读并没有太多收获,一是有点困...
    柔和谦卑阅读 181评论 0 0
  • 蟹肥菊开枝叶黄,山高冷清明月光。 醉醒石旁不知时,竟忘今夜已重阳。
    徐一村阅读 117评论 0 2