题目:1391. Check if There is a Valid Path in a Grid
1.思路:
典型的已知起点终点判断是否存在路径问题
考虑BFS和DFS的解法,这类问题一般在时间复杂度上 BFS > DFS
对于此类问题
- 1.用数组表示移动方向
- 2.用Set或者Array记录已经访问过的结点
- 3.BFS->Queue 是否到达终点的判断 是否超出边界 加入下一步的位置
这道题的特别之处在于grid分为了六种Street,也就是说需要考虑是否能够移动到下一个grid以及只能向哪个方向移动
2.涉及到的知识点:
如何判断是否能从一个grid移动到另外一个grid ?
比如横着走的Street1就不能移动到Street2
可以考虑对每一种Street都添加移动的限制条件,可是这样每种Street就需要判断两次 需要写 2*6条if语句。。
所以可以考虑反向考虑路径是否合法 比如gridA移动到gridB 判断gridB 是否可以移动到gridA
3.代码
var hasValidPath = function(grid) {
// direction left/up/right/donw = l/u/ri/d = 0/1/2/3
//current positision m n
// 1 -> ri : m n+1 / l :m n-1
// 2 -> d: m+1 n / u : m-1 n
// 3 -> ri:m+1 n / u : m n-1
// 4 -> ri:m n+1 / u :m+1 n
// 5 -> d: m n-1 / ri:m-1 n
// 6 -> l: m-1 n / d :m n+1
let dir = [[[0,1],[0,-1]],
[[1,0],[-1,0]],
[[1,0],[0,-1]],
[[0,1],[1,0]],
[[0,-1],[-1,0]],
[[-1,0],[0,1]]
]
let vit = new Set();
let row = grid.length;
let col = grid[0].length;
let max = row*col - 1;
let queue = [];
queue.push([0,0]);
while(queue.length){
let cur = queue.shift();
let cur_r = cur[0], cur_c = cur[1];
if(cur_r == row - 1 && cur_c == col - 1) return true;
vit.add(cur_r * col + cur_c);
let path = grid[cur_r][cur_c] - 1;
for(let next of dir[path]){
let next_r = cur_r + next[0];
let next_c = cur_c + next[1];
if(next_r < 0 || next_c < 0 || next_r >= row || next_c >= col || vit.has(next_c+ col * next_r)) continue;
let nextPath = grid[next_r][next_c] - 1;
for(let back of dir[nextPath]){
if(back[0] + next_r == cur_r && back[1] + next_c == cur_c){
queue.push([next_r,next_c]);
}
}
}
}
return false;
};
4.时间复杂度&空间复杂度
- Time Complexity: BFS ->访问每一个grid o(m*n) Input的大小
- Space Complexity: BFS -> Queue的大小 o(m*n) Input的大小