package com.cm.algorithm;
/*迷宫问题*/
import com.cm.utils.LogUtils;
import java.util.Stack;
public class Maze {
private static final String TAG = "Maze";
private static final boolean DEBUG = false;
public static class Point {
int x;
int y;
public int getX() {
return this.x;
}
public int getY() {
return this.y;
}
public Point(int x, int y) {
this.x = x;
this.y = y;
}
public boolean equal (Point p) {
return this.x == p.x && this.y == p.y;
}
}
/**
* 获取x和y最长公共子序列
* @param maze 地图 0 可以走 1不能走
* @return 左上角到左下角的路线(数据保证唯一解)
*/
public static Stack<Point> go(int[][] maze) {
if(maze == null) {
return new Stack<>();
}
int n = maze.length;
int m = maze[0].length;
int minL = n * m + 1; //记录当前最短值
Stack<Point> nowRoute = new Stack<Point>(); //记录当前路线
Stack<Point> result = new Stack<Point>(); //记录结果
boolean[][] visited = new boolean[n][m]; //标记是否访问
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (maze[i][j] == 0) {
visited[i][j] = false;
} else {
visited[i][j] = true;
}
}
}
int[][] dir = {{1, 0}, {0, 1}}; //定义四个方向
Point out = new Point(n - 1, m - 1); //入口
Point in = new Point(0, 0); //出口
visited[in.x][in.y] = true;
nowRoute.push(in);
while (!nowRoute.isEmpty()) {
Point up = nowRoute.peek();
if (up.equal(out)) {
if(DEBUG) {
LogUtils.beginDebugLog(TAG);
System.out.println("find result!");
LogUtils.endDebugLog(TAG);
}
if (nowRoute.size() < minL) {
writeResult(nowRoute, result);
minL = nowRoute.size();
}
nowRoute.pop();
if (!nowRoute.empty()) {
nowRoute.pop();
}
continue;
}
int dirNum = dir.length;
boolean flag = true; //标注这个点是否需要弹出
for(int i = 0; i < dirNum; i++) {
Point nextPoint = new Point(up.x + dir[i][0], up.y + dir[i][1]);
if (nextPoint.x >= 0 && nextPoint.x < n
&& nextPoint.y >=0 && nextPoint.y < m
&& !visited[nextPoint.x][nextPoint.y]) {
nowRoute.push(nextPoint);
visited[nextPoint.x][nextPoint.y] = true;
flag = false;
break;
}
}
if(flag) {
nowRoute.pop();
}
}
return reverseStack(result);
}
/**
* @param data
* @param result
*/
private static void writeResult(Stack<Point> data, Stack<Point> result) {
result.clear();
if (data != null) {
for(Point point : data) {
result.push(new Point(point.x, point.y));
}
}
}
private static Stack<Point> reverseStack(Stack<Point> stack) {
Stack<Point> reverseStack = new Stack<>();
while (!stack.isEmpty()) {
reverseStack.push(stack.pop());
}
return reverseStack;
}
}