经典递归问题--走迷宫(解题代码java)

555 阅读2分钟

经典递归问题--走迷宫(解题代码java)

题目:上一篇【广度优先搜索/深度优先搜索练习】

广搜代码

输入

20
0 1 0 0 1 1 0 1 1 1 1 0 0 0 0 0 1 0 1 0 
0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 1 1 
0 0 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0 1 
0 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 1 1 0 1 
1 0 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0 
1 0 1 1 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0 
0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 0 0 1 1 
1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 0 0 1 0 1 
0 1 0 1 0 0 0 1 0 1 1 0 1 1 1 0 1 0 1 0 
0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 1 1 1 1 0 
0 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 
1 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 1 1 0 0 
0 0 1 1 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0 
1 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 
0 1 1 0 1 1 0 1 0 1 0 1 1 1 0 0 0 1 1 1 
1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 
1 1 0 0 1 1 1 0 1 0 1 1 1 0 0 0 1 0 0 0 
1 1 1 0 1 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1 
1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 
0 1 0 1 1 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0

输出

开始执行
bfs: 最小步数:43   耗时:0 毫秒
import java.util.Scanner;

public class 广搜2
{
    /**
     * 方向数组  上下左右
     */
    static int d[][]={{0,-1},{-1,0},{0,1},{1,0}};
    /**
     * 坐标队列数据
     */
    static int q[][];
    /**
     * 迷宫地图数组
     */
    static int used[][];
    /**
     * 步数
     */
    static int step = 1;
    static int n = 0;
    public static void main(String[] args)
    {
        //加载迷宫地图,初始化迷宫地图数组
        Scanner in=new Scanner(System.in);
        n = in.nextInt();
        used=new int[n][n];
        for(int i=0;i<n;i++) {
            for (int j = 0; j < n; j++) {
                used[i][j] = in.nextInt();
            }
        }

        q=new int [10000000][2];

        System.out.println("开始执行");
        //记录程序开始时间
        long startTime = System.currentTimeMillis();

        //广搜。找出最短路劲,计算步数(主要程序)
        bfs(0,0);

        //记录程序结束时间
        long endTime = System.currentTimeMillis();
        //打印步数,程序耗时
        System.out.println(String.format("bfs: 最小步数:%s   耗时:%s 毫秒", step,(endTime-startTime)));



    }
    static void bfs(int x,int y){


        //r-h = 第n步有几种走法
        //h=当前队列索引
        //r=索引最大值
        int r=0,h=0;

        //在队列中记录当前坐标
        q[r][0]=x;
        q[r][1]=y;

        r++;

        //把当前坐标设置为已走过
        used[x][y]=1;
        int size;
        while(h<r){
            size=r-h;
            step++;
            while ((--size)>=0) {
                for (int i = 0; i < 4; i++) {

                    //获取下一步坐标
                    x = q[h][0] + d[i][0];
                    y = q[h][1] + d[i][1];

                    //判断下一步可行或已走过
                    if (x >= 0 && x < n && y >= 0 && y < n && used[x][y] != 1) {
                        //到终点
                        if (x == n-1 && y == n-1) {
                            return;
                        }
                        //把下一步设置为已走过
                        used[x][y] = 1;
                        q[r][0] = x;
                        q[r][1] = y;
                        r++;
                    }
                }
                h++;
            }
        }
    }
}

深搜代码

输入

20
0 1 0 0 1 1 0 1 1 1 1 0 0 0 0 0 1 0 1 0 
0 1 0 0 0 1 0 1 0 1 1 0 0 1 0 0 0 0 1 1 
0 0 0 1 0 0 1 0 1 1 1 0 1 1 1 1 0 0 0 1 
0 0 1 0 1 0 1 1 0 1 0 0 0 1 0 0 1 1 0 1 
1 0 0 1 0 0 1 1 0 0 0 1 1 1 1 0 1 1 1 0 
1 0 1 1 0 1 1 1 0 0 0 0 0 1 1 0 1 1 1 0 
0 0 0 0 0 0 0 1 1 1 0 1 1 1 1 1 0 0 1 1 
1 0 1 0 0 0 1 1 0 0 1 1 1 1 1 0 0 1 0 1 
0 1 0 1 0 0 0 1 0 1 1 0 1 1 1 0 1 0 1 0 
0 0 0 1 0 0 1 1 0 1 0 0 1 0 0 1 1 1 1 0 
0 1 1 1 1 0 0 0 0 0 1 1 1 1 0 0 1 0 1 0 
1 0 1 0 0 1 0 0 1 0 1 1 1 0 0 0 1 1 0 0 
0 0 1 1 1 0 1 1 1 0 1 0 0 1 0 0 1 1 0 0 
1 1 0 0 0 1 0 1 0 0 0 0 0 1 0 0 1 0 1 0 
0 1 1 0 1 1 0 1 0 1 0 1 1 1 0 0 0 1 1 1 
1 0 0 0 0 0 0 1 0 0 0 0 1 0 0 0 0 0 0 0 
1 1 0 0 1 1 1 0 1 0 1 1 1 0 0 0 1 0 0 0 
1 1 1 0 1 1 1 1 1 0 1 1 0 0 1 0 0 0 0 1 
1 1 0 0 0 0 0 0 0 0 0 0 0 1 0 0 0 0 1 1 
0 1 0 1 1 1 1 1 1 0 0 1 0 0 0 1 0 0 0 0

输出

开始执行
dfs: 最小步数:43   耗时:1235 毫秒
import java.util.Scanner;


/*
0 1 0 0 0
0 1 0 1 0
0 0 0 1 0
0 1 1 1 0
0 0 0 1 0
相对于广度优先访问,深度优先的方式更像是一条路走到黑,走不下去了再回到上个路口选择另外一条路。
 */
public class 深搜2
{
    /**
     * 方向数组  上下左右
     */
    static int d[][]={{0,-1},{-1,0},{0,1},{1,0}};

    /**
     * 迷宫地图数组
     */
    static int used[][];

    static int n = 0;

    /**
     * 步数   初始化为int最大值
     */
    static int step = Integer.MAX_VALUE;

    public static void main(String[] args){

        //加载迷宫地图,初始化迷宫地图数组
        Scanner in=new Scanner(System.in);
        n = in.nextInt();
        used=new int[n][n];
        for(int i=0;i<n;i++) {
            for (int j = 0; j < n; j++) {
                used[i][j] = in.nextInt();
            }
        }

        //设置出发点  从左上角也就是(0,0)坐标开始
        int x=0,y=0;

        System.out.println("开始执行");
        //记录程序开始时间
        long startTime = System.currentTimeMillis();

        //深搜。找出最短路劲,计算步数(主要程序)
        dfs(x,y,1);

        //记录程序结束时间
        long endTime = System.currentTimeMillis();

        //打印步数,程序耗时
        System.out.println(String.format("dfs: 最小步数:%s   耗时:%s 毫秒", step,(endTime-startTime)));
    }

    /**
     * 深搜
     * @param x x坐标 (used一维数组索引)
     * @param y y坐标  (used二维数组索引)
     * @param dpt  深搜深度 (等于步数)
     */
    static void dfs(int x,int y,int dpt){

        //判断当前坐标是不是墙壁或者已走过
        if(x<0||x>=n||y<0||y>=n||used[x][y]==1){
            return;
        }
        //走到终点。对比步数。记录最小步数
        if(x==n-1&&y==n-1){
            step = step > dpt ? dpt : step;
        }

        //从当前节点,往上下左右四个方向寻找下一步可行点
        for (int i=0;i<4;i++){
            int xx = x+d[i][0];     //下一步的x坐标
            int yy = y+d[i][1];     //下一步的y坐标
            used[x][y]=1;           //把当前坐标设置为已走过

            //下一步
            dfs(xx,yy,dpt+1);

            //回溯

            used[x][y]=0;           //还原当前坐标设置为未走过
        }

    }
}