用3*3求最短路径DFS
有两个需要注意的点
- 每次for循环都前往4个方向,执行了的方向不能重复(每个方向只能执行一次)
- 不能回到原来的位置
实现代码
package 算法练习;
public class 利用深度优先求最短路径 {
static int[][] arr=new int[4][4];
static int[][] ans=new int[4][4];
static int[][] fang= {
{1,0},{0,1},{-1,0},{0,-1}
};
static int min=999999;
public static void main(String[] args) {
// TODO Auto-generated method stub
dfs(1,1,0);
System.out.println(min);
}
static void dfs(int x, int y, int step) {
if(x==3&&y==3)
{
System.out.println(step);
if(step<min)
{
min=step;
}
//这个return是回到原来前面调用它的dfs里面
return;
}
//顺时针走
for(int i=0;i<3;i++)
{
// System.out.print("x="+x+" ");
// System.out.print("y="+y+" ");
//如果超过界限,跳过本次循环
if(x<=0||y<=0||x>3||y>3)
{
continue;
}
//如果回到原来的位置,跳过本次循环
if(ans[x][y]==1)
{
continue;
}
//如果前面没有执行continue,就标记走过的坐标
ans[x][y]=1;
dfs(x+fang[i][0],y+fang[i][1],step+1);
ans[x][y]=0;
}
}
}
题目院子啊哈算法!万能的搜索
第一行有两个数n m。n表示迷宫的行,m表示迷宫的列,接下来的n行m列为迷宫,0表示空地,1表示障碍物。最后一行4个数,前两个数位迷宫入口的x和y坐标。后两个位小哈的x和y坐标
输入为
0 0 1 0
0 0 0 0
0 0 1 0
0 1 0 0
0 0 0 1
1 1 4 3
package 算法练习;
import java.util.Scanner;
public class 解救小哈 {
static int min=999999;
static int[][] fang= {
{0,1},{1,0},{0,-1},{-1,0}
};
//迷宫的路径坐标
static int[][] arr=new int[6][5];
//走过的坐标
static int[][] ans=new int[6][5];
static void dfs(int x,int y,int step)
{
//如果到达目的地
if(x==4&&y==3)
{
if(step<min)
{
min=step;
}
//返回上一层
return;
}
//顺时针走
for(int i=0;i<4;i++)
{
//如果超过界限+回到原来的位置+碰到障碍物
if(x<=0||y<=0||x>5||y>4||ans[x][y]==1||arr[x][y]==1)
{
continue;
}
//如果前面的continue没执行,那就标记走过的坐标,然后继续往4个方向走
ans[x][y]=1;
dfs(x+fang[i][0],y+fang[i][1],step+1);
ans[x][y]=0;
}
}
public static void main(String[] args) {
// TODO Auto-generated method stub
Scanner in=new Scanner(System.in);
//迷宫的行列
int hang=5;
int lie=4;
//迷宫的数组
for(int i=1;i<=5;i++)
for(int j=1;j<=4;j++)
{
arr[i][j]=in.nextInt();
}
//标记第一个点的坐标为ans[1][1]=1
//这里的ans[x][y]==1有问题
// ans[1][1]=1;
int step=0;
dfs(1,1,0);
System.out.println(min);
}
}
用BFS求解3*3的最短路线
package 算法练习;
public class bfs {
//方向数组
static int[][] fang= {{0,1},{1,0},{0,-1},{-1,0}};
static class dian
{
int x;
int y;
int step;
//标记是否走过
int bji;
}
public static void main(String[] args) {
// TODO Auto-generated method stub
//创建路径数组arr
int x1=3;
int y1=3;
int[][] arr=new int[4][4];
//创建一个栈存放元素ans,寻找答案
int head=0;
int tail=0;
dian[] ans=new dian[999];
//遍历class
for(int i=0;i<999;i++)
{
ans[i]=new dian();
}
//设置循环标志
int flag=1;
//从1,1开始
ans[0].x=1;
ans[0].y=1;
//
int k=0;
while(flag==1)
{
//四个方向
for(int i=0;i<4;i++)
{
// System.out.print(ans[head].x+" ");
// System.out.print(ans[head].y+" ");
//这里的k叠加
k=k+1;
ans[k].x=ans[head].x+fang[i][0];
ans[k].y=ans[head].y+fang[i][1];
// System.out.print(ans[k].x+" ");
// System.out.print(ans[k].y+" ");
ans[k].step=ans[head].step+1;
//如果超过界限+回到原来的位置+重复到达某个坐标
if(ans[k].x<=0||ans[k].y<=0||ans[k].x>=4||ans[k].y>=4)
{
k=k-1;
continue;
}
if(ans[k].bji==1)
{
k=k-1;
continue;
}
//走过的标记为1
ans[k].bji=1;
//栈增加一个元素,栈就后移一位
tail=tail+1;
if(ans[tail].x==x1&&ans[tail].y==y1)
{
//输出最短步数
System.out.println(ans[k].step);
flag=0;
break;
}
}
//同一级的都执行完4个方向,head才加1,不然step会有问题
head=head+1;
if(flag==0)
{
break;
}
}
}
}