题意

题目

思路

我一开始的时候想的是最简单的方法,就是遍历所有的值为1的元素,再根据其为起点进行BFS,计算层数,但是这个方法超时了;

其实,可以不用从1开始遍历,从0开始遍历,找到和值为1相邻的0,将其的层数设置为1就行了,为什么可以不用从1开始,因为并没有要求从规定的起点到指定的位置,计算最小距离,而是计算一整个周围,只要周围存在1,则将其加入到队列,计算相应的距离(又可能存在别多个1包围的1的情况),注意的是,在访问过1的结点后下次不可以再进行计算。

实现

//
// #include "../PreLoad.h" class Solution {
public: /**
* 三重循环,最外层为所有1的结点,里面两层是实现BFS
* 导致时间复杂度过高,待优化
* @param matrix
* @return
*/
vector< vector<int>> layouts = {{-1, 0}, {1, 0}, {0, -1}, {0, 1}}; vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
vector<vector<int>> result(matrix);
if (matrix.size() == 0) {
return result;
} size_t row = matrix.size();
size_t col = matrix[0].size(); deque<pair<int, int>> queues;
vector<vector<int>> visited(row, vector<int>(col , 0)); bool isHaveOne = false;
for (size_t i = 0; i < row; i++) {
for (size_t j = 0; j < col; j++) {
if (matrix[i][j]) {
queues.push_back({i, j});
isHaveOne = true;
}
}
} if (!isHaveOne) {
return result;
} while (!queues.empty()) {
auto content = queues.front();
queues.pop_front(); bool found = false;
int level = 0; deque<pair<int, int>> tqueue;
tqueue.push_back(content); vector<vector<int>> tvisited(visited);
tvisited[content.first][content.second] = 1; while (!found && !tqueue.empty()) {
level++; int queue_len = tqueue.size();
// 保证队列中的每个数都能加上基本的平方数
for (int i = 0; i < queue_len; i++) {
auto tcontent = tqueue.front();
tqueue.pop_front(); for (auto temp : layouts) {
int newx = tcontent.first + temp[0];
int newy = tcontent.second + temp[1]; if (newx < 0 || newy < 0 || newx >= row || newy >= col || tvisited[newx][newy]) {
continue;
} if (!matrix[newx][newy]) {
found = true;
break;
} tvisited[newx][newy] = 1;
tqueue.push_back({newx, newy});
}
}
} tvisited = visited; result[content.first][content.second] = level;
} return result;
} // 做法错误
vector<vector<int>> updateMatrix2(vector<vector<int>>& matrix) {
vector<vector<int>> result(matrix);
if (matrix.size() == 0) {
return result;
} size_t row = matrix.size();
size_t col = matrix[0].size(); deque<pair<int, int>> queues; bool isHaveOne = false;
for (size_t i = 0; i < row; i++) {
for (size_t j = 0; j < col; j++) {
if (matrix[i][j]) {
queues.push_back({i, j});
isHaveOne = true;
}
}
} if (!isHaveOne) {
return result;
} vector<vector<int>> visited(row, vector<int>(col , 0));
vector<vector<int>> tvisited(visited);
while (!queues.empty()) {
auto content = queues.front();
queues.pop_front(); int level = 0;
bool found = false; DFSHelper(matrix, result, visited, level, content.first, content.second, row, col, found); tvisited = visited;
//result[content.first][content.second] = level;
} return result;
} // 无法保证取得的路径是最短的,因为是深度递归,所以有可能找的那条路径全都是1的,所以这样使用DFS是错误的
void DFSHelper(vector<vector<int>>& matrix, vector<vector<int>>& result, vector<vector<int>>& visited,
int& dis, int x, int y, int row, int col, bool& found) {
if (found) {
return ;
} dis++;
visited[x][y] = 1; if (!matrix[x][y]) {
result[x][y] = dis;
found = true;
return ;
}
else {
for (auto temp : layouts) {
int newx = x + temp[0];
int newy = y + temp[1]; if (found) {
return ;
} if (newx < 0 || newy < 0 || newx >= row || newy >= col || visited[newx][newy]) {
continue;
} DFSHelper(matrix, result, visited, dis, newx, newy, row, col, found); if (found) {
return ;
}
}
}
dis--;
visited[x][y] = 0;
} /**
* 将二维数组中为0的加入到队列中,1的则置为-1
* 因为必然存在和1的元素相邻的元素0,所以当找到这样的周围是1的0时
* 则把这个1的元素同样加入到队列中,因为可能会存在被1包围的1
* 同时设置其距离,这个则需要将其值设为初始元素的值(同样是1的元素)+1,
* 这个时候其的值不再是-1,同时起到了纪录其已经访问过了的作用
*
* 可以理解为如果上一个(初始位置)如果是0,则说明其在周围,自然为1
* 但是也会碰到被1包围的1,同样根据上面计算出来的1去计算后面的1的元素
* 有些dp的思想
*
* @param matrix
* @return
*/
vector<vector<int>> updateMatrix3(vector<vector<int>>& matrix) {
vector<vector<int>> result(matrix);
if (matrix.size() == 0) {
return result;
} size_t row = matrix.size();
size_t col = matrix[0].size(); typedef pair<int, int> tp; deque<pair<int, int>> queues;
for (size_t i = 0; i < row; i++) {
for (size_t j = 0; j < col; j++) {
if (matrix[i][j] == 0) {
queues.push_back(tp(i, j));
}
else {
result[i][j] = -1;
}
}
} while (!queues.empty()) {
auto content = queues.front();
queues.pop_front(); for (auto temp : layouts) {
int newx = content.first + temp[0];
int newy = content.second + temp[1]; if (newx >= 0 && newx < row && newy >= 0 && newy < col && result[newx][newy] == -1) {
result[newx][newy] = result[content.first][content.second] + 1; //注意不是自增
queues.push_back({newx, newy});
}
}
} return result;
} // 计算层数,并将其设置为负数,作为访问过的标记
vector<vector<int>> updateMatrix4(vector<vector<int>>& matrix) {
if (matrix.size() == 0) {
return matrix;
} size_t row = matrix.size();
size_t col = matrix[0].size(); typedef pair<int, int> tp; deque<pair<int, int>> queues;
for (size_t i = 0; i < row; i++) {
for (size_t j = 0; j < col; j++) {
if (matrix[i][j] == 0) {
queues.push_back(tp(i, j));
}
}
} int dis = 0;
while (!queues.empty()) {
dis++; int queue_len = queues.size();
// 保证队列中的每个数都能加上基本的平方数
for (int i = 0; i < queue_len; i++) {
auto content = queues.front();
queues.pop_front(); for (auto temp : layouts) {
int newx = content.first + temp[0];
int newy = content.second + temp[1]; if (newx >= 0 && newx < row && newy >= 0 && newy < col && matrix[newx][newy] == 1) {
matrix[newx][newy] = -dis; //做标记
queues.push_back({newx, newy});
}
}
}
} for(int i = 0; i < row; ++i){
for(int j = 0; j < col; ++j)
if(matrix[i][j] < 0) matrix[i][j] = -matrix[i][j];
} return matrix;
} void test() {
vector< vector<int>> water = {
{0, 0, 0},
{0, 1, 0},
{0, 0, 0},
}; vector<vector<int>> result = this->updateMatrix4(water);
for (auto i = 0; i < result.size(); i++) {
for (auto j = 0; j < result[0].size(); j++) {
cout << result[i][j] << ", ";
}
cout << endl;
}
}
};

[LeetCode] 01 Matrix 题解的更多相关文章

  1. [LeetCode] 01 Matrix 零一矩阵

    Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. The distance b ...

  2. [Leetcode] 01 Matrix

    问题: https://leetcode.com/problems/01-matrix/#/description 基本思路:广度优先遍历,根据所有最短距离为N的格找到所有距离为N+1的格,直到所有的 ...

  3. [Leetcode Week10]01 Matrix

    01 Matrix 题解 原创文章,拒绝转载 题目来源:https://leetcode.com/problems/01-matrix/description/ Description Given a ...

  4. 【LeetCode】01 Matrix 解题报告

    [LeetCode]01 Matrix 解题报告 标签(空格分隔): LeetCode 题目地址:https://leetcode.com/problems/01-matrix/#/descripti ...

  5. [leetcode] 542. 01 Matrix (Medium)

    给予一个矩阵,矩阵有1有0,计算每一个1到0需要走几步,只能走上下左右. 解法一: 利用dp,从左上角遍历一遍,再从右下角遍历一遍,dp存储当前位置到0的最短距离. 十分粗心的搞错了col和row,改 ...

  6. leetcode 542. 01 Matrix 、663. Walls and Gates(lintcode) 、773. Sliding Puzzle 、803. Shortest Distance from All Buildings

    542. 01 Matrix https://www.cnblogs.com/grandyang/p/6602288.html 将所有的1置为INT_MAX,然后用所有的0去更新原本位置为1的值. 最 ...

  7. LeetCode: Spiral Matrix II 解题报告-三种方法解决旋转矩阵问题

    Spiral Matrix IIGiven an integer n, generate a square matrix filled with elements from 1 to n2 in sp ...

  8. 计算机学院大学生程序设计竞赛(2015’12)01 Matrix

    01 Matrix Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total ...

  9. hdu 01 Matrix

    Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/Others) Total Submission ...

随机推荐

  1. Linux 菜鸟学习笔记--系统分区

    硬盘分区 常识 主分区:最多只能有4个 扩展分区:用于突破主分区最多4个的限制 *最多只能有1个 *主分区+扩展分区最多有4个 *不能写入数据,只能包含逻辑分区 逻辑分区 格式化:实际是写入文件系统, ...

  2. 初识Jenkins

    近期,接手了一个活,我要搭一个Jenkins持续集成的平台,所以,就把这次工作的收获分享给大家了. Jenkins是什么 Jenkins插件配置 Jenkins怎么用 新建job 系统配置 添加用户 ...

  3. Exception in thread "main" org.hibernate.HibernateException: save is not valid without active transaction

    在spring4+hibernate4整合过程中,使用@Transactional注解事务会报"Exception in thread "main" org.hibern ...

  4. 使用devstack搭建openstack Newton 版本的坑

    国外源访问速度慢怎么办? 使用国外源,加之带宽紧张,搭建过程是很累的,这里推荐大家使用一下源: devstack包源.:http://git.trystack.cn pip源: [global] in ...

  5. matlab中小技巧

    关于matlab中可能遇到的小知识点 一.字符串的比较 不能使用“==”,需要使用函数strcmp() %matlab中字符串的比较 %字符串比较要用strcmp.相同则返回1,不相同则返回0. cl ...

  6. Unity编程标准导引-2.2Unity中的基本概念

    2.2Unity中的基本概念 上述介绍提到了几个概念:游戏对象.场景.资源.相机,这个小节我们来深入了解,同时进行一些实践性操作.不过首先,我们需要大概了解一下Unity的工程文件夹. 2.2.1工程 ...

  7. [故障公告]博客站点遭遇超过20G的流量攻击被阿里云屏蔽

    2017年2月21日17:34,突然收到阿里云的通知: 您的IP受到攻击流量已超过云盾DDoS基础防护的带宽峰值,服务器的所有访问已被屏蔽,如果35分钟后攻击停止将自动解除否则会延期解除... 紧接着 ...

  8. BZOJ 1095: [ZJOI2007]Hide 捉迷藏(线段树维护括号序列)

    这个嘛= =链剖貌似可行,不过好像代码长度很长,懒得打(其实是自己太弱了QAQ)百度了一下才知道有一种高大上的叫括号序列的东西= = 岛娘真是太厉害了,先丢链接:http://www.shuizilo ...

  9. 关于OpenGL和DX学习的取舍

    大家多知道左右就肯定要与显卡打交道.两大图形图像IPA.OpenGL(图形),DX(图形,声音,键盘控制,网络) OpenGL的兴起可能取决于苹果公司的适用,吸引看大部分开发者适用,它有跨平台的有点. ...

  10. WP8.1开发中ListView控件加载图列表的简单使用(1)

    我也是刚接触WP编程没几个月,就是在这段时间一直闲着没事,然后又比较喜欢WP这款系统,就学习了WP这方面的开发言语,自学是很困难的,掌握这方面的资料不多,很初级,就是自己在网上找资料学习过程中,看到别 ...