Java实现Dfs算法(基本讲解)

目录

一、Dfs算法的概念

二、Dfs算法的设计步骤

三、Dfs算法模板

四、Dfs算法经典例题

(1)全排列

(2)N皇后


一、Dfs算法的概念

Depth First Search 即 DFS,意为深度优先搜索,是所有的搜索手段之一。它是从某个状态开始,不断进行状态转移,直到不能转移后,向后回退,一直到遍历完所有的状态。

作为搜索算法的一种,DFS 主要是用于解决 NP 完全问题。但是,深度优先搜索算法的时间复杂度较高,深度优先搜索是  O(n!) 的阶乘级算法,它的效率非常低,在数据规模变大时,此算法就难以解决当前的问题了。

二、Dfs算法的设计步骤

按照定义设计:

  1. 确定该题目的状态(包括边界)

  2. 找到状态转移方式

  3. 找到问题的出口,计数或者某个状态

  4. 设计搜索

int check(参数)
{
    if(满足条件)
        return 1;
    return 0;
}
bool pd(参数){
    相应操作
}
void dfs(int step)
{
        判断边界pd()
        {
            不在边界内,即回溯
        }
        尝试每一种可能
        {
               满足check条件

               标记

               继续下一步dfs(step+1)

               恢复初始状态(回溯的时候要用到)
        }
}

三、Dfs算法模板

public static int dfs(int step){
        if(当前状态=目标状态){
            return ...;
        }
        for(查找新状态){
            标记状态;
            dfs(下一状态);
            撤销状态标记,也就是回溯;
        }
   }

四、Dfs算法经典例题

(1)全排列

题目描述

按照字典序输出自然数 11 到 �n 所有不重复的排列,即 �n 的全排列,要求所产生的任一数字序列中不允许出现重复的数字。

输入格式

一个整数 �n。

输出格式

由 1∼�1∼n 组成的所有不重复的数字序列,每行一个序列。

每个数字保留 55 个场宽。

输入输出样例

输入 #1复制

3

输出 #1复制

    1    2    3
    1    3    2
    2    1    3
    2    3    1
    3    1    2
    3    2    1

说明/提示

1≤�≤91≤n≤9。


import java.util.*;

public class Main {
    static int[] v=new int[20];//判断数i是否访问
    static int n;
    static int[] a=new int[20];//保存方案
    public static void main(String[] args) {
       Scanner scanner=new Scanner(System.in);
        n=scanner.nextInt();
       dfs(1);
    }
    public static void dfs(int x){
        //x表示第几个数了
        if(x>3){
           for(int i=1;i<=n;i++){
               System.out.print(a[i]+" ");
           }
           System.out.println();
        }
        for(int i=1;i<=n;i++){
            if(v[i]==0){
                a[x]=i;
                v[i]=1;
                dfs(x+1);
                v[i]=0;
            }
        }
    }
}

(2)N皇后

N 皇后问题是指在 n * n 的棋盘上要摆 n 个皇后,
要求:任何两个皇后不同行,不同列也不在同一条斜线上,
求给一个整数 n ,返回 n 皇后的摆法数。

数据范围: 1≤�≤91≤n≤9

要求:空间复杂度 �(1)O(1) ,时间复杂度 �(�!)O(n!)

例如当输入4时,对应的返回值为2,

对应的两种四皇后摆位如下图所示:

示例1

输入:

1

复制返回值:

1

复制

示例2

输入:

8

复制返回值:

92

import java.util.*;

public class Main {
    static int[] zx=new int[200];//左斜
    static int[] yx=new int[200];//右斜
    static int[] li=new int[30];//列
    static int n;
    static int sum=0;//记录方案数
    public static void main(String[] args) {
        Scanner scanner=new Scanner(System.in);
        n=scanner.nextInt();
        dfs(1);
        System.out.println(sum);
    }
    public static void dfs(int s){
        //s表示当前第几行
        if(s>n){
            sum++;
        }
        //循环找第几列
        for(int i=1;i<=n;i++){
            if(check(s,i)){
                li[i]=1;
                zx[s+i]=1;
                yx[s-i+100]=1;
                dfs(s+1);
                li[i]=0;
                zx[s+i]=0;
                yx[s-i+100]=0;
            }
        }
    }
    public static boolean check(int x,int y){
        //判断(x,y)是否满足条件
        if(li[y]==0&&zx[x+y]==0&&yx[x-y+100]==0){
            return true;
        }
        else{
            return false;
        }
    }

}

 

  • 9
    点赞
  • 38
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

菜到极致就是渣

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值