Java深搜和广搜

(1) 深度优先遍历 —— 模板题 AcWing 846. 树的重心(层序遍历,用到了回溯+剪枝,深搜没有一个常用的框架)

int dfs(int u)
{
    st[u] = true; // st[u] 表示点u已经被遍历过

    for (int i = h[u]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!st[j]) dfs(j);
    }
}
(2) 宽度优先遍历 —— 模板题 AcWing 847. 图中点的层次(最短路,宽搜有一个最常用的框架)

queue<int> q;
st[1] = true; // 表示1号点已经被遍历过
q.push(1);

while (q.size())
{
    int t = q.front();
    q.pop();

    for (int i = h[t]; i != -1; i = ne[i])
    {
        int j = e[i];
        if (!s[j])
        {
            st[j] = true; // 表示点j已经被遍历过
            q.push(j);
        }
    }
}

例子:

对123排列组合:

package com.huawei.it.acwing;

import java.io.IOException;

public class Main {
    private static final int n = 3;

    private static final int[] path = new int[10];

    private static final boolean[] st = new boolean[10];

    public static void main(String[] args) throws IOException {
        dfs(0);
    }

    private static void dfs(int u) {
        if (u == n) {
            for (int i = 0; i < n; i++) {
                System.out.print(path[i]);
            }
            System.out.println();
            return;
        }
        for (int i = 1; i <= n; i++) {
            if (!st[i]) {
                path[u] = i;
                st[i] = true;
                dfs(u + 1);
                st[i] = false;
            }
        }
    }
}

n皇后问题

方法一:

package com.huawei.it.acwing;

public class Main {
    private static final int n = 4;

    private static final int N = 20;

    private static final char[][] g = new char[N][N];

    private static final boolean[] col = new boolean[N];

    private static final boolean[] dg = new boolean[N];

    private static final boolean[] udg = new boolean[N];

    public static void main(String[] args) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                g[i][j] = '.';
            }
        }
        dfs(0);
    }

    private static void dfs(int u) {
        if (u == n) {
            for (int i = 0; i < n; i++) {
                for (int j = 0; j < n; j++) {
                    System.out.print(g[i][j]);
                }
                System.out.println();
            }
            System.out.println();
            return;
        }
        // 枚举第u行皇后放在哪一列,正对角线:b=u+i,反对角线:b=-u+i+n,u就是x,i就是y
        for (int i = 1; i <= n; i++) {
            if (!col[i] && !dg[u + i] && !udg[n - u + i]) {
                g[u][i] = 'Q';
                col[i] = dg[u + i] = udg[n - u + i] = true;
                dfs(u + 1);
                col[i] = dg[u + i] = udg[n - u + i] = false;
                g[u][i] = '.';
            }
        }
    }
}

方法二:

package com.huawei.it.acwing;

public class Main {
    private static final int n = 4;

    private static final int N = 20;

    private static final char[][] g = new char[N][N];

    private static final boolean[] row = new boolean[N];

    private static final boolean[] col = new boolean[N];

    private static final boolean[] dg = new boolean[N];

    private static final boolean[] udg = new boolean[N];

    public static void main(String[] args) {
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                g[i][j] = '.';
            }
        }
        dfs(0, 0, 0);
    }

    private static void dfs(int x, int y, int s) {
        if (y == n) {
            y = 0;
            x++;
        }
        if (x == n) {
            if (s == n) {
                for (int i = 0; i < n; i++) {
                    for (int j = 0; j < n; j++) {
                        System.out.print(g[i][j]);
                    }
                    System.out.println();
                }
                System.out.println();
            }
            return;
        }
        // 不放皇后
        dfs(x, y + 1, s);
        // 放皇后
        if (!row[x] && !col[y] && !dg[x + y] && !udg[x - y + n]) {
            g[x][y] = 'Q';
            row[x] = col[y] = dg[x + y] = udg[x - y + n] = true;
            dfs(x, y + 1, s + 1);
            row[x] = col[y] = dg[x + y] = udg[x - y + n] = false;
            g[x][y] = '.';
        }
    }
}

BFS:

在一个n*m的二维数组里走迷宫,0表示可以走,1表示不可以走。从左上角(1,1)走到右下角(n,m),问至少需要移动多少次。

基本框架:

queue<——初始

while(queue不空) {

        t<——队头

        扩展t

}

package com.huawei.it.acwing;

import java.util.LinkedList;
import java.util.Queue;
import java.util.Scanner;

/*
走迷宫样例::
5
4
0 0 0 0
1 1 0 1
0 0 0 0
0 1 1 1
0 0 0 0
*/
public class Main {
    public static void main(String[] args) {
        Scanner sc = new Scanner(System.in);
        int n = sc.nextInt();
        int m = sc.nextInt();
        int[][] Maze = new int[n][m]; //迷宫
        int[][] dist = new int[n][m]; //记录该该位置到入口的最短距离

        //迷宫初始化
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < m; j++) {
                Maze[i][j] = sc.nextInt();
                dist[i][j] = -1;
            }
        }
        int[] start = new int[] {0, 0};//起点坐标
        int[][] directions = new int[][] {{-1, 0}, {0, 1}, {1, 0}, {0, -1}};//四个方向
        dist[0][0] = 0;//起点距离

        //宽搜(BFS)找到最短路径
        Queue<int[]> queue = new LinkedList<>();
        queue.add(start);
        while (!queue.isEmpty()) {
            int[] temp = queue.poll();
            for (int[] direction : directions) {
                int x = temp[0] + direction[0];
                int y = temp[1] + direction[1];
                if (x >= 0 && x < n && y >= 0 && y < m && Maze[x][y] == 0 && dist[x][y] == -1) {
                    dist[x][y] = dist[temp[0]][temp[1]] + 1;
                    queue.add(new int[] {x, y});
                    System.out.println("(" + x + "," + y + ")");
                }
            }
        }
        System.out.println(dist[n - 1][m - 1]);
        sc.close();
    }
}

  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值