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

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

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

aa014f106817

百度词条中的解释

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

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

(1)访问顶点v;

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

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

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

aa014f106817

题目

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

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

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

aa014f106817

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种的放法。我们把图放上来,方便大家理解。

aa014f106817

开始

aa014f106817

第一步

aa014f106817

第二步

aa014f106817

第三步,记录数字123

aa014f106817

第四步

aa014f106817

第五步

aa014f106817

第六步

aa014f106817

第七步,记录数字132

后面图略。。。

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

aa014f106817

9个数的排列组合

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

aa014f106817

实例代码

aa014f106817

运行结果

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

aa014f106817

初始化与book

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

aa014f106817

放卡片

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

aa014f106817

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

aa014f106817

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

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

aa014f106817

C\C++示例代码

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

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

aa014f106817

C\C++示例代码

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

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

本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.mzph.cn/news/442945.shtml

如若内容造成侵权/违法违规/事实不符,请联系多彩编程网进行投诉反馈email:809451989@qq.com,一经查实,立即删除!

相关文章

java数组元素是类_Java数组及其常用类

本文由疯狂软件教育中心整理,更多Java等高新技术,疯狂软件期待与你交流。一、JAVA中的数组(1)数组的定义:是有相同类型的、用一个标识符名称封装到一起的一个对象序列或基本数据类型数据序列。数组是一种最简单的复合数据类型。数组可以是一维…

java 数组 equals_java中用equals比较两个内容相同的字符数组

********************************************你在数组上调用函数equals,比较的是c和ch的地址改成if(Arrays.equals(ch,c));就可以比较c和ch的内容了********************************************java.sun.com上说,The equals method for class Object implements…

java ssh pdf_JavaSSH框架技术规范.pdf

航安项目(三期)框架技术规范日期 版本 简述 作者2011年3月1 日 V1.0 指定本系统的技术规范2011年9月25 日 V2.0 指定本系统的技术规范框架技术规范航安项目框架技术规范 目录1、规范配置说明12、系统三层架构规范配置说明12.1 Dao22.2 Entity42.3 Service43、Spring 规范配置说…

java 线程执行结束_Java_如何等待子线程执行结束

本程序的数据有可能是如下:main thread work startsub thread start working.main thread work done.now waiting sub thread done.sub thread stop working.now all done.忽略标号, 当然输出也有可能是1和2调换位置了. 这个我们是无法控制的. 我们看下线程的join操作, 究竟干了…

mysql将时间轴转化为时间_MySQL日期计算及格式转换有关问题

mysql日期计算及格式转换问题2012-06-09 21:08 MySQL日期计算及格式转换问题做开发的时候经常会碰到以下几个问题使用mysql的内置函数将时间轴转成对应的日期方法一:使用from_unixtime(unix_timestamp)函数即可实现,如:SELECT FROM_UNIXTIME(…

java 配置文件加密_Java在配置文件中加密密码?

小编典典一种简单的方法是在Java中使用基于密码的加密。这使你可以使用密码来加密和解密文本。这基本上意味着初始化一个javax.crypto.Cipherwith算法"AES/CBC/PKCS5Padding"并从javax.crypto.SecretKeyFactory该"PBKDF2WithHmacSHA512"算法获取密钥。这是…

java语言特点 字符串不变_面试必问:Java中String类型为什么设计成不可变的?

这几天在各大平台上都看到过这样一些帖子,全都是关于String类型对象不可变的问题,当然现在也是找工作的准备时期,因此花了一部分时间对其进行整理一下。想要完全了解String,在这里我们需要解决以下几个问题(1)什么是不可变对象&am…

java socket android_Android:这是一份很详细的Socket使用攻略

前言Socket的使用在 Android网络编程中非常重要今天我将带大家全面了解 Socket 及 其使用方法目录示意图1.网络基础阅读本文前,请先了解 关于计算机网络基础,如计算机体系结构、TCP、UDP等知识2. Socket定义即套接字,是应用层 与 TCP/IP 协议…

内构函数java_Android JNI参数传递

Java中调用native函数传递的参数是Java数据类型,到了JNI层需进行数据类型转换,基本数据类型是在前面加个j,如int——>jint,应用数据类型除了基本数据类型的数据、Class、String和Throwable外,其余所有Java对象的数据…

java 垃圾回收机制_Java的垃圾回收机制

前言在C语言中, 程序员必须小心谨慎的处理每一项内存分配, 且内存使用完后必须手动释放曾经占用的内存空间。当内存释放不够完全时, 即存在分配但永不释放的内存块, 就会引起"内存泄漏"问题。而在Java语言中, 它给了程序员一个美好的承诺: 程序员无需管理内存, 因为J…

java闹钟程序声音_跪求高手帮忙写一个JAVA手机闹钟程序 实现添加铃声和设置多闹钟...

展开全部import java.util.*;import java.awt.*;import java.applet.*;import java.text.*;public class AlarmClock extends Applet implements Runnable{Thread timernull; //创建线程timerImage clockp,gif1,gif2,clock6,clock7; //clockp:闹钟的外壳,闹铃和e68a…

摩托罗拉ex232java_摩托罗拉ex232r如何刷机?摩托罗拉ex232r评测

导语:随着 高科 技产业的发展,手机作为一个深受影响的产业,其竞争的激烈程度也是不言而喻的。市场好比战场,而为了在这个手机战场中赢 得胜 利,不论国内或者是国外的各大厂商也都全身心的投入到新技术的开发和新产品的…

java 对象序列化 数组_序列化-将任何对象转换为j中的字节数组

您要执行的操作称为“序列化”。 有几种方法可以做到,但是如果您不需要花哨的东西,我认为使用标准Java对象序列化就可以了。也许您可以使用这样的东西?package com.example;import java.io.ByteArrayInputStream;import java.io.ByteArrayOut…

java中gradlew 命令_gradle命令学习

概述命令学习比较枯燥,全部是例子~gradle版本假设你的本地gradle已经安装配置完成。没有安装配置的,可以参考 gradle安装C:\Users\yueling.DANGDANG>gradle -v------------------------------------------------------------Gradle 4.5.1------------…

java jsp常见问题_Java和Jsp编程中应注意的几个常见问题

1、对应String类型的对象使用println()方法时,如果对象为null,将打印null而不是引发NullPointerException,由此引用的问题是容易造成错觉,对于以后对字符串的操作容易引起问题。2、引发NullPointerException异常,主要原…

JAVA捕捉输入格式异常_Java学习(四).异常处理

异常处理任何一个软件或程序都可能在运行的过程中出现故障,问题的关键是故障出现以后如何处理?谁来处理?怎样处理?处理后系统能否恢复正常的运行?本章在介绍Java处理这类问题基本方法的基础上,讨论包含异常…

java1.5以后新增的特性_jdk1.5之后的一些新特性

oreach与数组加强的for循环(Enhanced forLoop)for(type element : array) {System.out.println(element)....}int[] arr {1, 2, 3, 4, 5};for(int element : arr)System.out.println(element);泛型(Generics)• J2SE5.0之后,针对泛型(Generics)设计的解决方…

php去除html属性,PHP如何去掉所有HTML标签?

PHP如何去掉所有HTML标签?在PHP中可以使用“strip_tags()”函数将字符串中的所有HTML标签去除,该函数用于从字符串中去除HTML和 PHP标记,其语法是“strip_tags(str)”,其参数str表示要进行操作的字符串,返回值为处理后…

php启用 asynchdns,在 PHP 中使用 Promise + co/yield 协程

摘要: 我们知道 JavaScript 自从有了 Generator 之后,就有了各种基于 Generator 封装的协程。其中 hprose 中封装的 Promise 和协程库实现了跟 ES2016 的 async/await 一样的功能,并且更加灵活。我们还知道 PHP 自从 5.5 之后,也引入了 Gener…

php 获取agent,PHP代码 解析HTTP_USER_AGENT 获取客户端操作系统

*** 获取客户端操作系统信息包括win10* param null* author Jea杨* return string*/function GetOS(){$agent $_SERVER[HTTP_USER_AGENT];$os false;if (preg_match(/win/i, $agent) && strpos($agent, 95)){$os Windows 95;}else if (preg_match(/win 9x/i, $age…