JAVA算法:解救小哈(JAVA版)
有一天,小哈一个人去玩迷宫。但是方向感不好的小哈很快就迷路了。小哼得知后便去解救无助的小哈。此时的小哼已经弄清楚了迷宫的地图,现在小哼要以最快的速度去解救小哈。那么,问题来了...
迷宫地图表示:0—表示通路;1—表示障碍
第一组用例:
输入迷宫坐标
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
小哈的位置:(3,2)
输出
7
第二组用例:
输入迷宫坐标
1 1 1
0 1 0
0 1 0
输出
No Way!
算法分析
迷宫表示
0 | 0 | 1 | 0 |
0 | 0 | 0 | 0 |
0 | 0 | 1 | 0 |
0 | 1 | 0 | 0 |
0 | 0 | 0 | 1 |
方向定义
1,1 | 1,2 | 1,3 |
2,1 | 2,2 | 2,3 |
3,1 | 3,2 | 3,3 |
设定一个坐标系的话,如下方格所示:
(X-1,Y) | ||
(X,Y-1) | (X,Y) | (X,Y+1) |
(X+1,Y) |
也就是说纵向用X轴表示,横向用Y轴表示。这个坐标轴非常重要,因为我们以此构建方向数组:
//搜索顺序:右,下,左,上
int[][] next=new int[][] {
{0,1},//向右走
{1,0},//向下走
{0,-1},//向左走
{-1,0} //向上走
};
算法设计
package com.bean.algorithm.dfsbfs;
import java.util.LinkedList;
public class HelpXiaoHa {
/**
* 定义迷宫数组
*/
private int maxY = 4;
private int maxX = 5;
int min=Integer.MAX_VALUE;
int endX=3;
int endY=2;
int[][] maze=new int[maxX][maxY];
int[][] mark=new int[maxX][maxY];
LinkedList<Integer> map=new LinkedList<Integer>();
/*
* 初始化迷宫
* */
public void initMaze() {
this.maze = new int[][] {
{ 0, 0, 1, 0 },
{ 0, 0, 0, 0 },
{ 0, 0, 1, 0 },
{ 0, 1, 0, 0 },
{ 0, 0, 0, 1 }
};
this.mark=new int[maxX][maxY];
this.mark[0][0]=1;
//输出迷宫地图,其中: * 代表障碍物;_代表可以通过
for(int x=0;x<maxX;x++) {
for(int y=0;y<maxY;y++) {
if(x==endX && y==endY) {
System.out.print("! ");
}else if(this.maze[x][y]==1) {
System.out.print("* ");
}else {
System.out.print("_ ");
}
}
System.out.println();
}
System.out.println();
}
public void dfs(int startX,int startY,int step) {
//搜索顺序:右,下,左,上
int[][] next=new int[][] {
{0,1},//向右走
{1,0},//向下走
{0,-1},//向左走
{-1,0} //向上走
};
int nextX;
int nextY;
int posible;
//判断是否达到小哈的位置
if(startX==endX && startY==endY) {
//判断是否用了最少的步数steps
if(step<min) {
min=step;
}
for(int i=map.size()-1;i>=0;i-=2) {
nextX=map.get(i);
nextY=map.get(i-1);
System.out.print("["+nextX+","+nextY+"]");
if(i!=1) {
System.out.print("->");
}
}
System.out.println();
return;
}
for(posible=0;posible<next.length;posible++) {
//顺序:右,下,左,上
//计算下一个点的坐标
nextX=startX+next[posible][0];
nextY=startY+next[posible][1];
//判断是否越界
if(nextX<0||nextX>=maxX||nextY<0||nextY>=maxY) {
continue;
}
if(maze[nextX][nextY]==0 && mark[nextX][nextY]==0) {
map.push(nextX);
map.push(nextY);
mark[nextX][nextY]=1;
dfs(nextX,nextY,step+1); //递归调用,移动到下一格子
mark[nextX][nextY]=0;
map.pop();
map.pop();
}
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
HelpXiaoHa help=new HelpXiaoHa();
int startX=0;
int startY=0;
long startTime=System.currentTimeMillis();
help.initMaze();
help.dfs(startX, startY, 0);
if(help.min<Integer.MAX_VALUE) {
System.out.println("At least "+help.min+" steps.");
}else {
System.out.println("No Way!");
}
long endTime=System.currentTimeMillis();
System.out.println("Elapsed time: "+(endTime-startTime)+" ms.");
}
}
程序运行结果:
_ _ * _
_ _ _ _
_ _ * _
_ * ! _
_ _ _ *
[0,1]->[1,1]->[1,2]->[1,3]->[2,3]->[3,3]->[3,2]
[0,1]->[1,1]->[2,1]->[2,0]->[3,0]->[4,0]->[4,1]->[4,2]->[3,2]
[0,1]->[1,1]->[1,0]->[2,0]->[3,0]->[4,0]->[4,1]->[4,2]->[3,2]
[1,0]->[1,1]->[1,2]->[1,3]->[2,3]->[3,3]->[3,2]
[1,0]->[1,1]->[2,1]->[2,0]->[3,0]->[4,0]->[4,1]->[4,2]->[3,2]
[1,0]->[2,0]->[2,1]->[1,1]->[1,2]->[1,3]->[2,3]->[3,3]->[3,2]
[1,0]->[2,0]->[3,0]->[4,0]->[4,1]->[4,2]->[3,2]
At least 7 steps.
Elapsed time: 4 ms.