递归 求解迷宫问题 Java

1 篇文章 0 订阅
1 篇文章 0 订阅

目录

题目描述:

解题思路:

代码分析:


题目描述:

        如图所示有一个 3X4 的迷宫,其中黑色方框代表墙,白色方框代表可通行,指定迷宫的入口和出口,计算出入口到出口的路径

解题思路:

        1.先将迷宫地图看成二维数组,可以粗略认为数组下标为坐标轴,(涉及到数组就要保证数组下标不越界!!!) 

        2.怎么移动?数组横坐标纵坐标+1 或者 -1视为移动一步, 每次只能移动一步(横纵坐标只能加一次)

        3.移动的方向最多4个方向,上下左右。

  x-1 , y
  x , y-1  x  ,  y  x , y+1
  x+1 , y

        4.可以在二维数组中 设置1为墙 0 为可以走的路

        5.每走一步需要记录当前的坐标

        6.走之前要判断所走的位置是否可走(数组下标越界 位置为1 等等)

算法代码:

package com.zgdx.maze;

import java.util.ArrayList;
import java.util.List;
import java.util.Scanner;

public class Maze {
    public static void main(String[] args) {
        //获取地图 map
        int [][] map = draw();
        //获取起点位置和终点位置
        int [] benAndEnd = begAndEnd();
        //获取起点坐标
        int x = benAndEnd[0];
        int y = benAndEnd[1];
        //获取地图长度
        int len = map.length;
        int wid = map[0].length;
        //将终点设置为特殊的标记
        map[benAndEnd[2]][benAndEnd[3]] = 9;

        //用一个数组存储 走过的路线
        int [][] runner = map;
        //如果数组中走过了标记为8
        //再来一个集合 存路径
        List path = new ArrayList();
        //每走一步都加一个当前的坐标
        //path.add(x , y);

        run(map , runner , path , len , wid , x , y);

        //一共走了几步
        System.out.println("一共走了" + path.size() + "步");
        //走的路径
        for (int i = 0; i < path.size(); i++) {
            System.out.println(path.get(i));
        }

    }

    /**
     *
     * @return 数组0、1为起点坐标 2、3为终点坐标
     */
    public static int[] begAndEnd(){
        int[] begAndEnd = new int[4];
        //起点终点坐标
        System.out.println("请输入起点  例:0,0");
        Scanner s = new Scanner(System.in);
        String begin = s.nextLine();
        //将输入的字符以 , 分割 拆分成坐标
        int [] begins = strToInt(begin , ",");
        begAndEnd[0] = begins[0];
        begAndEnd[1] = begins[1];

        System.out.println("请输入终点  例:0,0");
        String end = s.nextLine();
        //将输入的字符以 , 分割 拆分成坐标
        int [] ends = strToInt(end , ",");
        begAndEnd[2] = ends[0];
        begAndEnd[3] = ends[1];

        return begAndEnd;
    }

    /**
     *
     * @return 返回绘制完成的地图
     */
    public static int [][] draw(){

        System.out.println("输入地图大小 例:3*4");
        Scanner s = new Scanner(System.in);
        String size = s.nextLine();
        //将输入的字符串以*拆分成地图的长和宽
        int [] maps = strToInt(size , "\\*");
        //地图的二维数组 大小为输入的两个数字
        int [][] map = new int[maps[0]][maps[1]];

        System.out.println("输入墙的坐标 输入0为结束  例:0,2 1,0 1,2 0");
        for ( ; ; ) {
            String wall = s.nextLine();
            //如果是0 结束输入
            if ("0".equals(wall)){
                break;
            }
            //将地图绘制上墙
            map[strToInt(wall , ",")[0]][strToInt(wall , ",")[1]] = 1;
        }
        return map;
    }

    /**
     *
     * @param str 传入一个需要拆分的字符串
     * @param split 传入一个拆分字符
     * @return nums 拆分后转换成数字的数组
     */
    public static int[] strToInt(String str, String split){

        int [] nums = new int[2];
        String [] strings = str.split(split);
        nums[0] = Integer.parseInt(strings[0]);
        nums[1] = Integer.parseInt(strings[1]);

        return nums;
    }

    /**
     *
     * 使用递归分别走所有的方向
     */
    public static void run(int[][] map , int [][] runner , List path , int len , int wid , int x , int y){
        //判断当前位置是否可以走
        if (x >= len || x < 0 || y >= wid || y < 0
                || map[x][y] == 1 || runner[x][y] == 8){
            return;
        }
        //判断当前位置是不是已经到终点了
        if (map[x][y] == 9){
            return;
        }
        //可以走标记当前位置
        runner[x][y] = 8;
        //把当前位置坐标存在集合中
        path.add(new Node(x , y));

        //继续走
        run(map , runner , path , len , wid , x+1 , y);
        run(map , runner , path , len , wid , x-1 , y);
        run(map , runner , path , len , wid , x , y+1);
        run(map , runner , path , len , wid , x , y-1);

        //清除失败的痕迹
//        runner[x][y] = 0;

    }
}

Node类体代码:

package com.zgdx.maze;

public class Node {
    int x;
    int y;

    public Node(int x, int y) {
        this.x = x;
        this.y = y;
    }

    @Override
    public String toString() {
        return "Node{" +
                "x=" + x +
                ", y=" + y +
                '}';
    }
}

问题总结:

  1.        把坐标轴替换成数组 在数组中设置可以走的地方 和墙壁
  2.        在当前位置是最多有4个方向可以走的  上下左右 让程序依次递归 也就是嗲用方法压栈
  3.       其实还有一些不足  后续再说 正在改进  比如最优解  最短路径问题 等等

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值