思路:广度优先遍历矩阵。代价相同的图中,广度优先遍历可以保证遍历到的目标点就是经过最短路径到达的点。为此,我们可以创建一个Point类,属性为横纵坐标和父节点。从(0,0)出发,将经过的坐标点都设为1,避免重复经过而进入死循环。把当前点的上下左右值为0的点都加入队列中,直到遇见出口为止。遇到出口时,pos的father路径就是最短路径的逆路径。此时只需要把逆路径反转一下即可。
Java版本:
import java.util.*;
class Point{
int px;
int py;
Point father;
Point(int px,int py,Point father){
this.px=px;
this.py=py;
this.father = father;
}
Point(){}
}
public class Main{
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int row = sc.nextInt();
int col = sc.nextInt();
int [][] grid = new int[row][col];
for(int i=0;i<row;++i){
for(int j=0;j<col;++j){
grid[i][j]=sc.nextInt();
}
}
Queue<Point> que = new LinkedList<Point>();
que.offer(new Point(0,0,null));
grid[0][0]=1;
Point pos = null;
while(true){
pos = que.poll();
int px = pos.px;
int py = pos.py;
if(px==row-1&&py==col-1)break;
else {
if(px+1<row&&grid[px+1][py]==0){
grid[px+1][py]=1;
que.offer(new Point(px+1,py,pos));
}
if(py-1>=0&&grid[px][py-1]==0){
grid[px][py-1]=1;
que.offer(new Point(px,py-1,pos));
}
if(px-1>=0&&grid[px-1][py]==0){
grid[px-1][py]=1;
que.offer(new Point(px-1,py,pos));
}
if(py+1<col&&grid[px][py+1]==0){
grid[px][py+1]=1;
que.offer(new Point(px,py+1,pos));
}
}
}
Stack<Point> stack = new Stack<Point>();
while(pos!=null){
stack.push(pos);
pos=pos.father;
}
while(!stack.isEmpty()){
Point temp = stack.peek();
stack.pop();
System.out.println("("+temp.px+","+temp.py+")");
}
}
}
}
利用递归可以后序输出链表的特性,可以省去反转路径的操作:
class Point{
int px;
int py;
Point father;
Point(int px,int py,Point father){
this.px=px;
this.py=py;
this.father = father;
}
Point(){}
}
public class Main{
public static void print(Point p){
if(p != null){
print(p.father);
System.out.println("("+p.px+","+p.py+")");
}
}
public static void main(String args[]){
Scanner sc = new Scanner(System.in);
while(sc.hasNextInt()){
int row = sc.nextInt();
int col = sc.nextInt();
int [][] grid = new int[row][col];
for(int i=0;i<row;++i){
for(int j=0;j<col;++j){
grid[i][j]=sc.nextInt();
}
}
Queue<Point> que = new LinkedList<Point>();
que.offer(new Point(0,0,null));
grid[0][0]=1;
Point pos = null;
while(true){
pos = que.poll();
int px = pos.px;
int py = pos.py;
if(px==row-1&&py==col-1)break;
else {
if(px+1<row&&grid[px+1][py]==0){
grid[px+1][py]=1;
que.offer(new Point(px+1,py,pos));
}
if(py-1>=0&&grid[px][py-1]==0){
grid[px][py-1]=1;
que.offer(new Point(px,py-1,pos));
}
if(px-1>=0&&grid[px-1][py]==0){
grid[px-1][py]=1;
que.offer(new Point(px-1,py,pos));
}
if(py+1<col&&grid[px][py+1]==0){
grid[px][py+1]=1;
que.offer(new Point(px,py+1,pos));
}
}
}
print(pos);
}
}
}