import java.util.*; public class Solution { private Step start; private Step end; private Queue<Step> queue = new LinkedList<>(); private final int[] dx = {0, 0, -1, 1}; private final int[] dy = {1, -1, 0, 0}; private int min = Integer.MAX_VALUE; private int result = 0; private boolean[][] isVisited; private int[][] dp; private int[][] dist; /** * 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可 * * * @param CityMap int整型二维数组 * @param n int整型 * @param m int整型 * @return int整型 */ public int countPath (int[][] CityMap, int n, int m) { // return solution1(CityMap, n, m); return solution2(CityMap, n, m); } /** * 广度优先搜索(BFS) * 适合最短路径 * * @param CityMap * @param n * @param m * @return */ private int solution1(int[][] CityMap, int n, int m){ for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ if(CityMap[i][j] == 1){ start = new Step(i, j, 0); } if(CityMap[i][j] == 2){ end = new Step(i, j); } } } queue.add(start); bfs1(CityMap, n, m); return result; } /** * 广度优先搜索(BFS) + 动态规划 * dp[i][j]表示到达点(i,j)处的最短路径的条数 * * @param CityMap * @param n * @param m * @return */ private int solution2(int[][] CityMap, int n, int m){ isVisited = new boolean[n][m]; dp = new int[n][m]; dist = new int[n][m]; for(int i=0; i<n; i++){ for(int j=0; j<m; j++){ if(CityMap[i][j] == 1){ start = new Step(i, j); dp[i][j] = 1; dist[i][j] = 0; } if(CityMap[i][j] == 2){ end = new Step(i, j); } } } queue.offer(start); isVisited[start.x][start.y] = true; bfs2(CityMap, n, m); return result; } /** * 广度优先搜索(BFS) * * @param CityMap * @param n * @param m */ private void bfs1(int[][] CityMap, int n, int m){ while(!queue.isEmpty()){ Step curr = queue.poll(); if(curr.level > min){ break; } if(curr.equals(end)){ min = curr.level; result++; continue; } Step next; int x,y; for(int i=0; i<4; i++){ x = curr.x+dx[i]; y = curr.y+dy[i]; if(canGo(CityMap, x, y, n, m)){ next = new Step(x, y, curr.level+1); queue.add(next); } } } } /** * 广度优先搜索(BFS) + 动态规划 * * @param CityMap * @param n * @param m */ private void bfs2(int[][] CityMap, int n, int m){ while(!queue.isEmpty()){ Step curr = queue.poll(); if(curr.equals(end)){ result = dp[end.x][end.y]; break; } Step next; int x,y; for(int i=0; i<4; i++){ x = curr.x+dx[i]; y = curr.y+dy[i]; if(canGo(CityMap, x, y, n, m)){ if(dist[x][y]==0 || dist[x][y]==dist[curr.x][curr.y]+1){ dist[x][y] = dist[curr.x][curr.y]+1; dp[x][y] += dp[curr.x][curr.y]; } if(!isVisited[x][y]){ next = new Step(x, y); queue.offer(next); isVisited[x][y] = true; } } } } } /** * 能否移动 * @param CityMap * @param x * @param y * @param n * @param m * @return */ private boolean canGo(int[][] CityMap, int x, int y, int n, int m){ // 行x越界 if(x<0 || n-1<x){ return false; } // 列y越界 if(y<0 || m-1<y){ return false; } // -1 代表不能经过的地区 if(CityMap[x][y] == -1){ return false; } return true; } private class Step { int x; int y; int level; public Step(int x, int y){ this.x = x; this.y = y; } public Step(int x, int y, int level){ this.x = x; this.y = y; this.level = level; } @Override public boolean equals(Object o){ if(this == o){ return true; } if(o == null || getClass() != o.getClass()){ return false; } Step step = (Step) o; return x == step.x && y == step.y; } } }