DFS定义

DFS(Depth-First-Search)深度优先搜索算法,是搜索算法的一种。是一种在开发爬虫早期使用较多的方法。它的目的是要达到被搜索结构的叶结点 。

特点

每次深度优先搜索的结果必然是图的一个连通分量。深度优先搜索可以从多点发起。如果将每个节点在深度优先搜索过程中的“结束时间”排序(具体做法是创建一个list,然后在每个节点的相邻节点都已被访问的情况下,将该节点加入list结尾,然后逆转整个链表),则我们可以得到所谓的“拓扑排序”,即topological sort.

当然,当人们刚刚掌握深度优先搜索的时候常常用它来走迷宫。事实上我们还有别的方法,那就是广度优先搜索 (BFS)。状态(state):状态是指问题求解过程中每一步的状况。

经典算法过程

图的深度遍历原则:

1 如果有可能,访问一个领接的未访问的节点,标记它,并把它放入栈中。

2 当不能执行规则 1 时,如果栈不为空,则从栈中弹出一个元素。

3 如果不能执行规则 1 和规则 2 时,则完成了遍历。

典型实例(兵临城下)

该题目是乐视的面试编程题

卢卡斯的驱逐者大军已经来到了赫柏的卡诺萨城,赫柏终于下定决心,集结了大军,与驱逐者全面开战。

卢卡斯的手下有6名天之驱逐者,这6名天之驱逐者各赋异能,是卢卡斯的主力。

为了击败卢卡斯,赫柏必须好好考虑如何安排自己的狂战士前去迎战。

狂战士的魔法与一些天之驱逐者的魔法属性是相克的,第i名狂战士的魔法可以克制的天之驱逐者的集合为Si(Si中的每个元素属于[0,5])。

为了公平,两名狂战士不能攻击同一个天之驱逐者。

现在赫柏需要知道共有多少种分派方案。

例:

S1={01},S2={23},代表编号为0的狂战士的魔法可以克制编号为0和编号为1的天之驱逐者,编号为1的狂战士的魔法可以克制编号为2和编号为3的天之驱逐者,共有四种方案:02,03,12,13。

02—代表第一个狂战士负责编号为0的驱逐者,第二个狂战士负责编号为2的驱逐者;

03—代表第一个狂战士负责编号为0的驱逐者,第二个狂战士负责编号为3的驱逐者;

12—代表第一个狂战士负责编号为1的驱逐者,第二个狂战士负责编号为2的驱逐者;

13—代表第一个狂战士负责编号为1的驱逐者,第二个狂战士负责编号为3的驱逐者;

S1={01},S2={01},代表编号为0的狂战士的魔法可以克制编号为0和编号为1的天之驱逐者,编号为1的狂战士的魔法可以克制编号为0和编号为1的天之驱逐者,共有两种方案:01,10。

输入描述:

多组测试数据,请处理到文件结束。

对于每组测试数据:

第一行为一个整数N,代表狂战士的数量。

第二行为N个字符串,第i个字符串表示第i个狂战士能够克制的天之驱逐者的集合。

保证:

1<=N<=6,1<=每个字符串的长度<=6,且每个字符都是0~5中的一个数字。

输出描述:

输出一个整数,代表分配方案数

输入例子:

2

01 23

2

01 01

3

3 015 5

输出例子:

4

2

2

分析:

1.对于这种遍历的问题,考虑采用经典的DFS,设置一个辅助的数组(题目要求不能两个人打一个),来记录是否是否是唯一的。

2.判断每个分支的截止条件,通过递归和循环完成遍历。

代码:

public class Main {

    private static int ans;

    public static int getAns(String[] str, int n) {
        ans = 0;
        int[] vis = {0, 0, 0, 0, 0, 0};
        dfs(str, vis, n, 0);
        return ans;
    }

    public static void dfs(String[] str, int[] vis, int n, int p) {
        if (p == n) {
            ans++;
            return ;
        }
        for (int i = 0; i < str[p].length(); i++) {
            if (vis[str[p].charAt(i) - '0'] == 0) {
                vis[str[p].charAt(i) - '0'] = 1;
                dfs(str, vis, n, p + 1);
                vis[str[p].charAt(i) - '0'] = 0;
            }
        }
    }

    public static void main(String[] args) {
        Scanner in = new Scanner(new BufferedInputStream(System.in));
        while (in.hasNext()) {
            int n = in.nextInt();
            String[] str = new String[n];
            for (int i = 0; i < n; i++) {
                str[i] = in.next();
            }

            int ans = getAns(str, n);
            System.out.println(ans);
        }
        in.close();
    }

}

引用:

牛客网的乐视题目

我的微信二维码如下,欢迎交流讨论

欢迎关注《IT面试题汇总》微信订阅号。每天推送经典面试题和面试心得技巧

微信订阅号二维码如下:

DFS(深度优先)算法编程实践的更多相关文章

  1. DFS深度优先算法学习

    刚开始学习算法,参考大佬博客还是有很多不明白的,于是一步步解析,写下笔记记录. 大佬博客地址: https://blog.csdn.net/fuzekun/article/details/852204 ...

  2. 广度优先算法(BFS)与深度优先算法(DFS)

    一.广度优先算法BFS(Breadth First Search) 基本实现思想 (1)顶点v入队列. (2)当队列非空时则继续执行,否则算法结束. (3)出队列取得队头顶点v: (4)查找顶点v的所 ...

  3. 回溯算法 DFS深度优先搜索 (递归与非递归实现)

    回溯法是一种选优搜索法(试探法),被称为通用的解题方法,这种方法适用于解一些组合数相当大的问题.通过剪枝(约束+限界)可以大幅减少解决问题的计算量(搜索量). 基本思想 将n元问题P的状态空间E表示成 ...

  4. [算法总结]DFS(深度优先搜索)

    目录 一.关于DFS 1. 什么是DFS 2. DFS的搜索方式 二.DFS的具体实现 三.剪枝 1. 顺序性剪枝 2. 重复性剪枝 3. 可行性剪枝 4. 最优性剪枝 5. 记忆化剪枝 四.练习 一 ...

  5. [ACM训练] 算法初级 之 搜索算法 之 深度优先算法DFS (POJ 2251+2488+3083+3009+1321)

    对于深度优先算法,第一个直观的想法是只要是要求输出最短情况的详细步骤的题目基本上都要使用深度优先来解决.比较常见的题目类型比如寻路等,可以结合相关的经典算法进行分析. 常用步骤: 第一道题目:Dung ...

  6. 高性能JavaScript 编程实践

    前言 最近在翻<高性能JavaScript>这本书(2010年版 丁琛译),感觉可能是因为浏览器引擎的改进或是其他原因,书中有些原本能提高性能的代码在最新的浏览器中已经失效.但是有些章节的 ...

  7. 第二章 C语言编程实践

    上章回顾 宏定义特点和注意细节 条件编译特点和主要用处 文件包含的路径查询规则 C语言扩展宏定义的用法 第二章 第二章 C语言编程实践 C语言编程实践 预习检查 异或的运算符是什么 宏定义最主要的特点 ...

  8. Java与算法之(5) - 老鼠走迷宫(深度优先算法)

    小老鼠走进了格子迷宫,如何能绕过猫并以最短的路线吃到奶酪呢? 注意只能上下左右移动,不能斜着移动. 在解决迷宫问题上,深度优先算法的思路是沿着一条路一直走,遇到障碍或走出边界再返回尝试别的路径. 首先 ...

  9. Python入门经典. 以解决计算问题为导向的Python编程实践

    Python入门经典. 以解决计算问题为导向的Python编程实践(高清版)PDF 百度网盘 链接:https://pan.baidu.com/s/1juLsew8UiOErRheQPOuTaw 提取 ...

随机推荐

  1. 【tyvj】刷题记录(1001~1099)(64/99)

    1001:排序完按照题意做即可. #include<cstdio> #include<iostream> #include<cmath> #include<a ...

  2. NOIP2014-5-17模拟赛

    Problem 1 双色球(ball.cpp/c/pas) [题目描述] 机房来了新一届的学弟学妹,邪恶的chenzeyu97发现一位学弟与他同名,于是他当起了善良的学长233 "来来来,学 ...

  3. hdu 5464(dp)

    题意: 给你n个数,要求选一些数(可以不选),把它们加起来,使得和恰好是p的倍数(0也是p的倍数),求方案数. - - 心好痛,又没想到动规 #include <stdio.h> #inc ...

  4. Codeforces Round #430 B. Gleb And Pizza

    Gleb ordered pizza home. When the courier delivered the pizza, he was very upset, because several pi ...

  5. Saltstack基础

    salt介绍 salt简单介绍 一个基础平台管理工具 一个配置管理系统,能够维护预定义状态的远程节点 一个分布式远程执行系统,用来在远程节点上执行命令和查询数据 salt的核心功能 使命令发送到远程系 ...

  6. Linux学习之CentOS(六)---mount挂载设备(u盘,光盘,iso等 )

    对于新手学习,mount 命令,一定会有很多疑问.其实我想疑问来源更多的是对linux系统本身特殊性了解问题. linux是基于文件系统,所有的设备都会对应于:/dev/下面的设备.如: [cheng ...

  7. Postgresql合并年月日、月份和日期左侧补零

    在写一个统计查询的 SQL 语句时,需要根据年.月.日分组,但要求返回的字段是日期格式:yyyy年MM月dd日.刚开始我的做法是返回年.月.日,然后再手动拼接年月日,而且还要判断月份和日期是否为个位数 ...

  8. [HCNA]VLAN配置Hybrid接口

    实验名称 VLAN配置Hybrid接口 日期 2018年4月13日 实验目的 1.掌握配置Hybrid接口的方法. 2.理解Hybrid接口处理Untagged数据帧过程 3.理解Hybrid接口处理 ...

  9. redis和spring集成

    redis和spring框架的整合 我这里创建的是maven工程,通过maven锁定版本号,管理jar包之间的依赖 1.在pom文件中,引入spring和redis的jar包的坐标: <prop ...

  10. ionic3-ng4学习见闻--(多语言方案)

    1.安装ng2-translate npm install ng2-translate --save 2.app.moudle.ts 引入模块,在下方新增方法 import { TranslateMo ...