题解 | #迷宫问题#
https://www.nowcoder.com/practice/cf24906056f4488c9ddb132f317e03bc
广度优先算法,
1、思路就是上左下右,把当前遍历到的都加到Stack中,遍历过的不用管,一直走到头了,就在Stack中pop出一个;继续
2、遍历了的就加上标记;
3、全图标记完后,方向遍历。
5 5 0 1 0 0 0 0 1 1 1 0 0 0 0 0 0 0 1 1 1 0 0 0 0 1 0↓↓变成这样↓↓↓↓
[10, 1, 0, 0, 0]
[11, 1, 1, 1, 17]
[11, 1, 1, 1, 17]
[12, 13, 14, 15, 16]
[13, 1, 1, 1, 17]
[0, 0, 0, 1, 18]
[13, 1, 1, 1, 17]
[0, 0, 0, 1, 18]
没什么难点,就是代码难看了点,需要优化。代码量至少减少2/3.
这个是临时写的,至少有4个地方可以优化。留给后来人。
import java.util.ArrayList; import java.util.Arrays; import java.util.Scanner; import java.util.Stack; /** * 广度优先算法,顺序可以是上左下右,也可以是上右下左。无论怎么走,都可以找出最短路径 */ public class Main { public static void main(String[] args) { Scanner in = new Scanner(System.in); int row = 0; int column = 0; int[][] grid = null; while (in.hasNext()) { row = in.nextInt(); column = in.nextInt(); grid = new int[row][column]; for (int i = 0; i < row; i++) { for (int j = 0; j < column; j++) { grid[i][j] = in.nextInt(); } } walk(grid, new Point(0, 0), new Point(row - 1, column - 1)); if (grid != null) { // 从右下角网上遍历 Stack<Point> all = new Stack<>(); int endValue = grid[row - 1][column - 1]; Point cPoint = new Point(row - 1, column - 1); all.push(cPoint); while (!(cPoint.i == 0 && cPoint.j == 0)) { Point p = find(grid, endValue, cPoint); cPoint = p; endValue -= 1; all.push(new Point(p.i, p.j)); } while (!all.isEmpty()) { Point pp = all.pop(); System.out.println("("+pp.i + "," + pp.j +")"); } } } } private static Point find(int[][] grid, int endValue, Point currentPoint) { currentPoint.goUp(); if (isAvil(grid, currentPoint) && grid[currentPoint.i][currentPoint.j] == endValue - 1) { Point newPoint = new Point(currentPoint.i, currentPoint.j); currentPoint.resetUp(); return newPoint; } currentPoint.resetUp(); currentPoint.goLeft(); if (isAvil(grid, currentPoint) && grid[currentPoint.i][currentPoint.j] == endValue - 1) { Point newPoint = new Point(currentPoint.i, currentPoint.j); currentPoint.resetLeft(); return newPoint; } currentPoint.resetLeft(); currentPoint.goDown(); if (isAvil(grid, currentPoint) && grid[currentPoint.i][currentPoint.j] == endValue - 1) { Point newPoint = new Point(currentPoint.i, currentPoint.j); currentPoint.resetDown(); return newPoint; } currentPoint.resetDown(); currentPoint.goRight(); if (isAvil(grid, currentPoint) && grid[currentPoint.i][currentPoint.j] == endValue - 1) { Point newPoint = new Point(currentPoint.i, currentPoint.j); currentPoint.resetRight(); return newPoint; } currentPoint.goRight(); return null; } private static class Point { private int i, j; public Point(int i, int j) { this.i = i; this.j = j; } @Override public String toString() { return "Point{" + "i=" + i + ", j=" + j + '}'; } public void goUp() { i--; } public void resetUp() { i++; } public void goDown() { i++; } public void resetDown() { i--; } public void goLeft() { j--; } public void resetLeft() { j++; } public void goRight() { j++; } public void resetRight() { j--; } } private static ArrayList<Point> hasDones = new ArrayList<>(); private static boolean isAvil(int[][] grid, Point point) { if (point.j < 0 || point.j >= grid[0].length) { return false; } else return point.i >= 0 && point.i < grid.length; } static int point = 10; /** * 开始走路了。 * * @param grid * @param start * @param end */ private static void walk(int[][] grid, Point start, Point end) { Point currentPoint = start; grid[start.i][start.j] = point; Stack<Point> array = new Stack<>(); while (!currentPoint.toString().equals(end.toString())) { point++; lookAround(grid, currentPoint, array); hasDones.add(currentPoint); if (!array.isEmpty()) { currentPoint = array.pop(); point = grid[currentPoint.i][currentPoint.j]; } } } /** * @param grid * @param currentPoint */ private static void lookAround(int[][] grid, Point currentPoint, Stack<Point> array) { currentPoint.goUp(); save(grid, currentPoint, array); currentPoint.resetUp(); currentPoint.goLeft(); save(grid, currentPoint, array); currentPoint.resetLeft(); currentPoint.goDown(); save(grid, currentPoint, array); currentPoint.resetDown(); currentPoint.goRight(); save(grid, currentPoint, array); currentPoint.resetRight(); } private static void save(int[][] grid, Point currentPoint, Stack<Point> array) { if (isAvil(grid, currentPoint)) { if (grid[currentPoint.i][currentPoint.j] == 0 && !hasCo(currentPoint)) { Point temp = new Point(currentPoint.i, currentPoint.j); array.push(temp); grid[currentPoint.i][currentPoint.j] = point; } } } private static boolean hasCo(Point currentPoint) { for (int i = 0; i < hasDones.size(); i++) { if (hasDones.get(i).toString().equals(currentPoint.toString())) { return true; } } return false; } }