1+ // Solution: bfs T: O(n) S: O(n)
2+ class Solution {
3+
4+ class Node {
5+ int row ;
6+ int col ;
7+ int step ;
8+ int obs ;
9+
10+ public Node (int row , int col , int step , int obs ) {
11+ this .row = row ;
12+ this .col = col ;
13+ this .step = step ;
14+ this .obs = obs ;
15+ }
16+ }
17+
18+ public int shortestPath (int [][] grid , int k ) {
19+ if (grid == null ) return -1 ;
20+ int n = grid .length ;
21+ if (grid [0 ] == null ) return -1 ;
22+ int m = grid [0 ].length ;
23+
24+ Queue <Node > queue = new LinkedList <>();
25+ Node start = new Node (0 , 0 , 0 , 0 );
26+ queue .offer (start );
27+
28+ Node [][] visited = new Node [n ][m ];
29+ visited [0 ][0 ] = start ;
30+
31+ // 移动方向
32+ int [] dx = new int []{-1 , 1 , 0 , 0 };
33+ int [] dy = new int []{0 , 0 , -1 , 1 };
34+
35+ while (!queue .isEmpty ()) {
36+ int sz = queue .size ();
37+ for (int i = 0 ; i < sz ; i ++) {
38+ Node tmp = queue .poll ();
39+ int row = tmp .row ;
40+ int col = tmp .col ;
41+ int step = tmp .step ;
42+ int obs = tmp .obs ;
43+ if (row == n -1 && col == m -1 ) {
44+ return step ;
45+ }
46+ // four direction
47+ for (int j = 0 ; j < 4 ; j ++) {
48+ int newRow = row + dx [j ];
49+ int newCol = col + dy [j ];
50+
51+ if (!checkBoundary (newRow , newCol , n , m )) continue ;
52+ int newObs = obs + (grid [newRow ][newCol ] == 1 ? 1 : 0 );
53+ if (newObs > k ) continue ;
54+ Node newNode = new Node (newRow , newCol , step +1 , newObs );
55+ // 第一次遍历
56+ if (visited [newRow ][newCol ] == null ) {
57+ visited [newRow ][newCol ] = newNode ;
58+ queue .offer (newNode );
59+ } else {
60+ // 不是第一次遍历该结点,但是新路线障碍物更少
61+ if (newObs < visited [newRow ][newCol ].obs ) {
62+ visited [newRow ][newCol ] = newNode ;
63+ queue .offer (newNode );
64+ }
65+ }
66+ }
67+ }
68+ }
69+ return -1 ;
70+
71+ }
72+
73+ public static boolean checkBoundary (int row , int col , int n , int m ) {
74+ if (row < 0 || row >= n ) return false ;
75+ if (col < 0 || col >= m ) return false ;
76+ return true ;
77+ }
78+ }
0 commit comments