题解 | #迷宫问题#
迷宫问题
http://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc
Java
使用了回溯的方法
(组合问题、切割问题、子集问题、排列问题、棋盘问题都可用回溯)
一般情况下的回溯模板:
void backtracking(参数){
if(终止条件){
收集结果(比如放入最大的List中);
return;
}
for(集合元素集(所有子节点个数)){
处理节点;(加入List,连接字符串等操作)
递归函数;
回溯操作;(撤销节点操作)
}
}
迷宫问题
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Scanner;
//迷宫问题
public class Main {
static List<List<Integer>> lists=new ArrayList<List<Integer>>();
public static void main(String[] args){
Scanner sc=new Scanner(System.in);
while (sc.hasNext()){
int x=sc.nextInt();
int y=sc.nextInt();
int[][] maze=new int[x][y];
for(int i=0;i<x;i++){
for(int j=0;j<y;j++){
maze[i][j]=sc.nextInt();
}
}
List<Integer> list=new ArrayList<>();
//创建一个新数组,用于放判断的值
int[][] hp=new int[x][y];
backtracking(maze,0,0,x,y,list,hp);
//题目中说找最短路径,就拿出lists中最短的list吧。对lists按长度排序
Collections.sort(lists, new Comparator<List<Integer>>() {
public int compare(List<Integer> o1, List<Integer> o2) {
return o1.size()-o2.size();
}
});//对lists的元素按照路径长度由小到大进行排序
list=lists.get(0);//拿出第一条路径(最短路径)
for (int i = 0; i < list.size(); i++) {
System.out.println("("+list.get(i)+","+list.get(++i)+")");
}
//还要输入多组数据呢
lists.clear();
}
}
//回溯函数
public static void backtracking(int[][] maze,int i,int j,int x,int y,List<Integer> list,int[][] hp){
//在这些条件下,返回
if(i<0||j<0||i==x||j==y||hp[i][j]==1||maze[i][j]==1){
return;
}
//到最右下的元素了
if(i==x-1&&j==y-1){
//或许因为最后一个也要添进去
list.add(i);
list.add(j);
lists.add(new ArrayList<Integer>(list));
list.remove(list.size()-1);//将list的终点坐标清除,回溯法的核心就是办完事(达到目标)一定要完全还原之前的状态
list.remove(list.size()-1);//这里的list是引用传递,所以不清除的话会一直带着终点坐标
return;
}
list.add(i);
list.add(j);
hp[i][j]=1;
//上下左右
backtracking(maze,i,j+1,x,y,list,hp);
backtracking(maze,i+1,j,x,y,list,hp);
backtracking(maze,i,j-1,x,y,list,hp);
backtracking(maze,i-1,j,x,y,list,hp);
hp[i][j]=0;
list.remove(list.size()-1);//回溯
list.remove(list.size()-1);
}
}借鉴了一位高赞回答
查看12道真题和解析
腾讯成长空间 5879人发布

