lintcode 787. The Maze 、788. The Maze II 、
787. The Maze
https://www.cnblogs.com/grandyang/p/6381458.html
与number of island不一样,递归的函数返回值是bool,不是void。
maze = -1用来表示已经访问的节点。
dp用来记录每个位置的是否能访问,如果dp != -1,就表示这个地方已经访问过了,可以避免多余的访问。
一直滑动用while循环来做,这里并没有没移动一次就增加一个访问。
int x = i,y = j必须这样写,因为之后的4种迭代都是从i、j这个位置出发,x、y在每一次迭代过程中已经发生了变化。
vector的初始化用{},如果是vector<vector<int>>,初始化用{{},{},{}}
class Solution { public: /** * @param maze: the maze * @param start: the start * @param destination: the destination * @return: whether the ball could stop at the destination */ bool hasPath(vector<vector<int>> &maze, vector<int> &start, vector<int> &destination) { // write your code here int m = maze.size(); if(m <= 0) return false; int n = maze[0].size(); if(n <= 0) return false; vector<vector<int>> dp(m,vector<int>(n,-1)); return hasPath(maze,dp,start[0],start[1],destination[0],destination[1]); } bool hasPath(vector<vector<int>>& maze,vector<vector<int>>& dp,int i,int j,int di,int dj){ if(i == di && j == dj) return true; if(dp[i][j] != -1) return dp[i][j]; maze[i][j] = -1; int m = maze.size(),n = maze[0].size(); bool res = false; for(auto dir : dirs){ int x = i,y = j; while(x >= 0 && x < m && y >= 0 && y < n && maze[x][y] != 1){ x += dir[0]; y += dir[1]; } x -= dir[0]; y -= dir[1]; if(maze[x][y] != -1) res |= hasPath(maze,dp,x,y,di,dj); } return res; } vector<vector<int>> dirs{{0,-1},{1,0},{0,1},{-1,0}}; };
自己写了一遍:
因为一直移动,所以需要一直进行dir的移动计算,直到不满足条件。
注意,这里
maze[new_x][new_y] != 1
而不是写的==0,对于-1的位置,也就是已经遍历过的点,你还是可以继续经过这里去其他地方。这个-1更多的是表示从这个点出发已经访问过了。
class Solution { public: /** * @param maze: the maze * @param start: the start * @param destination: the destination * @return: whether the ball could stop at the destination */ bool hasPath(vector<vector<int>> &maze, vector<int> &start, vector<int> &destination) { // write your code here if(maze.empty()) return false; if(maze[0].empty()) return false; if(start.empty() || destination.empty()) return false; return hasPath(maze,start[0],start[1],destination[0],destination[1]); } bool hasPath(vector<vector<int>>& maze,int x,int y,int destination_x,int destination_y){ if(x == destination_x && y == destination_y) return true; maze[x][y] = -1; bool flag = false; for(int i = 0;i < dirs.size();i++){ int new_x = x; int new_y = y; while(new_x >= 0 && new_x < maze.size() && new_y >= 0 && new_y < maze[0].size() && maze[new_x][new_y] != 1){ new_x += dirs[i][0]; new_y += dirs[i][1]; } new_x -= dirs[i][0]; new_y -= dirs[i][1]; if(maze[new_x][new_y] != -1) flag |= hasPath(maze,new_x,new_y,destination_x,destination_y); } return flag; } vector<vector<int>> dirs{{-1,0},{1,0},{0,-1},{0,1}}; };
788. The Maze II
思路:用一个矩阵记录到每个位置的最短距离,初始化为INT_MAX,如果终点到最后仍然为INT_MAX,则表明不可达
错误解法一:
这个解法使用了visited数组,表示已经被访问过,这容易造成有些地方不可达。如果从另一个方向到当前位置
class Solution { public: /** * @param maze: the maze * @param start: the start * @param destination: the destination * @return: the shortest distance for the ball to stop at the destination */ int shortestDistance(vector<vector<int>> &maze, vector<int> &start, vector<int> &destination) { // write your code here int m = maze.size(); if(m <= 0) return -1; int n = maze[0].size(); if(n <= 0) return -1; if(maze[start[0]][start[1]] == 1 || maze[destination[0]][destination[1]] == 1) return -1; vector<vector<int>> distance(m,vector<int>(n,INT_MAX)); vector<vector<bool>> visited(m,vector<bool>(n,false)); queue<pair<int,int>> q; q.push(make_pair(start[0],start[1])); distance[start[0]][start[1]] = 0; while(!q.empty()){ int x = q.front().first; int y = q.front().second; q.pop(); visited[x][y] = true; for(auto dir : dirs){ int x_new = x + dir[0]; int y_new = y + dir[1]; int des = distance[x][y]; while(x_new >= 0 && x_new < m && y_new >= 0 && y_new < n && !visited[x_new][y_new] && maze[x_new][y_new] == 0){ x_new += dir[0]; y_new += dir[1]; des++; } x_new -= dir[0]; y_new -= dir[1]; if(des < distance[x_new][y_new]){ distance[x_new][y_new] = des; if(x_new != destination[0] || y_new != destination[1]) q.push(make_pair(x_new,y_new)); } } } return distance[destination[0]][destination[1]] == INT_MAX ? -1 : distance[destination[0]][destination[1]]; } vector<vector<int>> dirs{{-1,0},{0,-1},{1,0},{0,1}}; };
错误解法二:
class Solution { public: /** * @param maze: the maze * @param start: the start * @param destination: the destination * @return: the shortest distance for the ball to stop at the destination */ int shortestDistance(vector<vector<int>> &maze, vector<int> &start, vector<int> &destination) { // write your code here int m = maze.size(); if(m <= 0) return -1; int n = maze[0].size(); if(n <= 0) return -1; if(maze[start[0]][start[1]] == 1 || maze[destination[0]][destination[1]] == 1) return -1; vector<vector<int>> distance(m,vector<int>(n,INT_MAX)); queue<pair<int,int>> q; q.push(make_pair(start[0],start[1])); distance[start[0]][start[1]] = 0; while(!q.empty()){ int x = q.front().first; int y = q.front().second; q.pop(); int des = distance[x][y]; for(auto dir : dirs){ int x_new = x + dir[0]; int y_new = y + dir[1]; while(x_new >= 0 && x_new < m && y_new >= 0 && y_new < n && maze[x_new][y_new] == 0){ x_new += dir[0]; y_new += dir[1]; des++; } x_new -= dir[0]; y_new -= dir[1]; if(des < distance[x_new][y_new]){ distance[x_new][y_new] = des; if(x_new != destination[0] || y_new != destination[1]) q.push(make_pair(x_new,y_new)); } } } return distance[destination[0]][destination[1]] == INT_MAX ? -1 : distance[destination[0]][destination[1]]; } vector<vector<int>> dirs{{-1,0},{0,-1},{1,0},{0,1}}; };
正确解法:
class Solution { public: /** * @param maze: the maze * @param start: the start * @param destination: the destination * @return: the shortest distance for the ball to stop at the destination */ int shortestDistance(vector<vector<int>> &maze, vector<int> &start, vector<int> &destination) { // write your code here int m = maze.size(); if(m <= 0) return -1; int n = maze[0].size(); if(n <= 0) return -1; if(maze[start[0]][start[1]] == 1 || maze[destination[0]][destination[1]] == 1) return -1; vector<vector<int>> distance(m,vector<int>(n,INT_MAX)); queue<pair<int,int>> q; q.push(make_pair(start[0],start[1])); distance[start[0]][start[1]] = 0; while(!q.empty()){ int x = q.front().first; int y = q.front().second; q.pop(); for(auto dir : dirs){ int x_new = x + dir[0]; int y_new = y + dir[1]; int des = distance[x][y]; while(x_new >= 0 && x_new < m && y_new >= 0 && y_new < n && maze[x_new][y_new] == 0){ x_new += dir[0]; y_new += dir[1]; des++; } x_new -= dir[0]; y_new -= dir[1]; if(des < distance[x_new][y_new]){ distance[x_new][y_new] = des; if(x_new != destination[0] || y_new != destination[1]) q.push(make_pair(x_new,y_new)); } } } return distance[destination[0]][destination[1]] == INT_MAX ? -1 : distance[destination[0]][destination[1]]; } vector<vector<int>> dirs{{-1,0},{0,-1},{1,0},{0,1}}; };