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 <= )
return false;
int n = maze[].size();
if(n <= )
return false;
vector<vector<int>> dp(m,vector<int>(n,-));
return hasPath(maze,dp,start[],start[],destination[],destination[]);
}
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] != -)
return dp[i][j];
maze[i][j] = -;
int m = maze.size(),n = maze[].size();
bool res = false;
for(auto dir : dirs){
int x = i,y = j;
while(x >= && x < m && y >= && y < n && maze[x][y] != ){
x += dir[];
y += dir[];
}
x -= dir[];
y -= dir[];
if(maze[x][y] != -)
res |= hasPath(maze,dp,x,y,di,dj);
}
return res;
}
vector<vector<int>> dirs{{,-},{,},{,},{-,}};
};

自己写了一遍:

因为一直移动,所以需要一直进行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[].empty())
return false;
if(start.empty() || destination.empty())
return false;
return hasPath(maze,start[],start[],destination[],destination[]);
}
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] = -;
bool flag = false;
for(int i = ;i < dirs.size();i++){
int new_x = x;
int new_y = y;
while(new_x >= && new_x < maze.size() && new_y >= && new_y < maze[].size() && maze[new_x][new_y] != ){
new_x += dirs[i][];
new_y += dirs[i][];
}
new_x -= dirs[i][];
new_y -= dirs[i][];
if(maze[new_x][new_y] != -)
flag |= hasPath(maze,new_x,new_y,destination_x,destination_y);
}
return flag;
}
vector<vector<int>> dirs{{-,},{,},{,-},{,}};
};

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 <= )
return -;
int n = maze[].size();
if(n <= )
return -;
if(maze[start[]][start[]] == || maze[destination[]][destination[]] == )
return -;
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[],start[]));
distance[start[]][start[]] = ;
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[];
int y_new = y + dir[];
int des = distance[x][y];
while(x_new >= && x_new < m && y_new >= && y_new < n && !visited[x_new][y_new] && maze[x_new][y_new] == ){
x_new += dir[];
y_new += dir[];
des++;
}
x_new -= dir[];
y_new -= dir[];
if(des < distance[x_new][y_new]){
distance[x_new][y_new] = des;
if(x_new != destination[] || y_new != destination[])
q.push(make_pair(x_new,y_new));
}
}
}
return distance[destination[]][destination[]] == INT_MAX ? - : distance[destination[]][destination[]];
}
vector<vector<int>> dirs{{-,},{,-},{,},{,}};
};

错误解法二:

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 <= )
return -;
int n = maze[].size();
if(n <= )
return -;
if(maze[start[]][start[]] == || maze[destination[]][destination[]] == )
return -;
vector<vector<int>> distance(m,vector<int>(n,INT_MAX));
queue<pair<int,int>> q;
q.push(make_pair(start[],start[]));
distance[start[]][start[]] = ;
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[];
int y_new = y + dir[];
while(x_new >= && x_new < m && y_new >= && y_new < n && maze[x_new][y_new] == ){
x_new += dir[];
y_new += dir[];
des++;
}
x_new -= dir[];
y_new -= dir[];
if(des < distance[x_new][y_new]){
distance[x_new][y_new] = des;
if(x_new != destination[] || y_new != destination[])
q.push(make_pair(x_new,y_new));
}
}
}
return distance[destination[]][destination[]] == INT_MAX ? - : distance[destination[]][destination[]];
}
vector<vector<int>> dirs{{-,},{,-},{,},{,}};
};

正确解法:

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 <= )
return -;
int n = maze[].size();
if(n <= )
return -;
if(maze[start[]][start[]] == || maze[destination[]][destination[]] == )
return -;
vector<vector<int>> distance(m,vector<int>(n,INT_MAX));
queue<pair<int,int>> q;
q.push(make_pair(start[],start[]));
distance[start[]][start[]] = ;
while(!q.empty()){
int x = q.front().first;
int y = q.front().second;
q.pop();
for(auto dir : dirs){
int x_new = x + dir[];
int y_new = y + dir[];
int des = distance[x][y];
while(x_new >= && x_new < m && y_new >= && y_new < n && maze[x_new][y_new] == ){
x_new += dir[];
y_new += dir[];
des++;
}
x_new -= dir[];
y_new -= dir[];
if(des < distance[x_new][y_new]){
distance[x_new][y_new] = des;
if(x_new != destination[] || y_new != destination[])
q.push(make_pair(x_new,y_new));
}
}
}
return distance[destination[]][destination[]] == INT_MAX ? - : distance[destination[]][destination[]];
}
vector<vector<int>> dirs{{-,},{,-},{,},{,}};
};

lintcode 787. The Maze 、788. The Maze II 、的更多相关文章

  1. 记录我的 python 学习历程-Day13 匿名函数、内置函数 II、闭包

    一.匿名函数 以后面试或者工作中经常用匿名函数 lambda,也叫一句话函数. 课上练习: # 正常函数: def func(a, b): return a + b print(func(4, 6)) ...

  2. leetcode 198. House Robber 、 213. House Robber II 、337. House Robber III 、256. Paint House(lintcode 515) 、265. Paint House II(lintcode 516) 、276. Paint Fence(lintcode 514)

    House Robber:不能相邻,求能获得的最大值 House Robber II:不能相邻且第一个和最后一个不能同时取,求能获得的最大值 House Robber III:二叉树下的不能相邻,求能 ...

  3. leetcode 263. Ugly Number 、264. Ugly Number II 、313. Super Ugly Number 、204. Count Primes

    263. Ugly Number 注意:1.小于等于0都不属于丑数 2.while循环的判断不是num >= 0, 而是能被2 .3.5整除,即能被整除才去除这些数 class Solution ...

  4. leetcode 344. Reverse String 、541. Reverse String II 、796. Rotate String

    344. Reverse String 最基础的旋转字符串 class Solution { public: void reverseString(vector<char>& s) ...

  5. 代码随想录第八天 |344.反转字符串 、541. 反转字符串II、剑指Offer 05.替换空格 、151.翻转字符串里的单词 、剑指Offer58-II.左旋转字符串

    第一题344.反转字符串 编写一个函数,其作用是将输入的字符串反转过来.输入字符串以字符数组 s 的形式给出. 不要给另外的数组分配额外的空间,你必须原地修改输入数组.使用 O(1) 的额外空间解决这 ...

  6. leetcode 136. Single Number 、 137. Single Number II 、 260. Single Number III(剑指offer40 数组中只出现一次的数字)

    136. Single Number 除了一个数字,其他数字都出现了两遍. 用亦或解决,亦或的特点:1.相同的数结果为0,不同的数结果为1 2.与自己亦或为0,与0亦或为原来的数 class Solu ...

  7. leetcode 112. Path Sum 、 113. Path Sum II 、437. Path Sum III

    112. Path Sum 自己的一个错误写法: class Solution { public: bool hasPathSum(TreeNode* root, int sum) { if(root ...

  8. leetcode 39. Combination Sum 、40. Combination Sum II 、216. Combination Sum III

    39. Combination Sum 依旧与subsets问题相似,每次选择这个数是否参加到求和中 因为是可以重复的,所以每次递归还是在i上,如果不能重复,就可以变成i+1 class Soluti ...

  9. 颜色转换、随机、16进制转换、HSV

    颜色转换.随机.16进制转换.HSV: /** * * *-----------------------------------------* * | *** 颜色转换.随机.16进制转换.HSV * ...

随机推荐

  1. OpenStack是什么,OpenStack详解

    1. OpenStack是什么 OpenStack官方的解释很官方,而且从不同角度,也有不同的理解,OpenStack可以理解为一个云操作系统 OpenStack旗下包含了一组由社区维护的开源项目,他 ...

  2. P1392 取数[堆]

    题目描述 在一个n行m列的数阵中,你须在每一行取一个数(共n个数),并将它们相加得到一个和.对于给定的数阵,请你输出和前k小的取数方法. 解析 写这题完全自闭. 根本没联想起远古时期做的 P1631 ...

  3. 零基础如何学好Python 之int 数字整型类型 定义int()范围大小转换

    本文主题是讲python数字类型python int整型使用方法及技巧.它是不可变数据类型中的一种,它的一些性质和字符串是一样的,注意是整型不是整形哦. Python int有多种数字类型:整型int ...

  4. EF映射——从数据库更新实体

    最近在做ITOO项目,由于更新了数据库,需要重新从数据库映射到实体,本来看过关于EF的学习资料,直接可以从数据库更新到实体,但这种小事也是有很多问题的,必须在更新的时候做好选择.下面分享一下如何从数据 ...

  5. 2019-2020-1 20199301《Linux内核原理与分析》第六周作业

    第五章 系统调用的三层机制(下) 1.给MenuOS增加命令 代码如下: rm -rf menu git clone http://github.com/mengning/menu.git make ...

  6. linux第三天

    一.用户的类型   1.root管理员:所有权限(r w x)   2.文件拥有者(u):谁创建谁拥有   3.组 (g):用户组   4.其它用户(o):不属于用户组,也不是文件的创建者,不是管理员 ...

  7. docker 进程 转载:https://www.cnblogs.com/ilinuxer/p/6188303.html

    今天我们会分析Docker中进程管理的一些细节,并介绍一些常见问题的解决方法和注意事项. 容器的PID namespace(名空间) 在Docker中,进程管理的基础就是Linux内核中的PID名空间 ...

  8. C++编译原理

    链接

  9. nginx配置静态资源:配置绝对路径

    nginx配置静态资源:配置绝对路径 项目都是html格式的文件,我的项目路径:E:\javaservice\nginx-1.15.7\html assets:静态资源 html:站点文件 uploa ...

  10. ML,DL核心数学及算法知识点总结

    ML,DL核心数学及算法知识点总结:https://mp.weixin.qq.com/s/bskyMQ2i1VMNiYKIvw_d7g