Date: 20200324
542. 01 Matrix
Given a matrix consists of 0 and 1, find the distance of the nearest 0 for each cell. The distance between two adjacent cells is 1.
基本信息
Difficulty: Medium
Related Topics: Depth-first Search,Breadth-first Search
v0.1.0
不在一条直线上的也算,实际是算曼哈顿距离最短的0在哪里。一开始我以为只是在同一行或者同一列上。不过看结果发现有点规律。
可以从(0,0)到(m,n),从上往下,从左往右过一遍,再从(m,n)到(0,0),从下往上,从右往左过一遍。
matrix[i][j]==0时,answer[i][j]==0。不为0时,再进行判断。
从上往下的时候,取answer[i-1][j]和answer[i][j-1]的中较小的值,加上1赋值给answer[i][j]。如果matrix[0][0]==0没那么计算很简单,如果matrix[0][0]==1怎么办呢?如果保持1的值,会对之后的遍历结果造成困扰,所以可以先赋值为-1,代表这个格子还没计算。
从下往上和上面描述的过程类似,就是计算变成answer[i][j],answer[i+1][j]+1和answer[i][j+1]+1之间最小值。
当格子在最边上的行和列时,根据位置分情况讨论。
#include <iostream>
#include <algorithm>
#include <limits>
using namespace std;
class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& matrix) {
vector<vector<int>> ans = matrix;
for (int i = 0; i < ans.size(); i++) {
for (int j = 0; j < ans[0].size(); j++) {
if (ans[i][j] != 0) {
if (i == 0 && j != 0) {
if (ans[i][j-1] != -1) {
ans[i][j] = ans[i][j-1] + 1;
} else {
ans[i][j] = -1;
}
} else if (i != 0 && j == 0) {
if (ans[i-1][j] != -1) {
ans[i][j] = ans[i-1][j] + 1;
}else {
ans[i][j] = -1;
}
} else if (i == 0 && j == 0) {
ans[i][j] = -1;
} else {
if (ans[i][j-1] == -1 && ans[i-1][j] != -1) {
ans[i][j] = ans[i-1][j] + 1;
} else if (ans[i][j-1] != -1 && ans[i-1][j] == -1) {
ans[i][j] = ans[i][j-1] + 1;
} else if (ans[i][j-1] == -1 && ans[i-1][j] == -1) {
ans[i][j] = -1;
} else {
ans[i][j] = min(ans[i][j-1], ans[i-1][j]) + 1;
}
}
}
}
}
for (int i = ans.size()-1; i >= 0; i--) {
for (int j = ans[0].size() - 1; j >= 0; j--) {
if (ans[i][j] != 0) {
if (i == ans.size()-1 && j != ans[0].size() - 1) {
if (ans[i][j] != -1) {
ans[i][j] = min(ans[i][j], ans[i][j+1]+1);
} else {
ans[i][j] = ans[i][j+1]+1;
}
} else if (i != ans.size()-1 && j == ans[0].size() - 1) {
if (ans[i][j] != -1) {
ans[i][j] = min(ans[i][j], ans[i+1][j]+1);
}else {
ans[i][j] = ans[i+1][j]+1;
}
} else if (i == ans.size()-1 && j == ans[0].size() - 1) {
ans[i][j] = ans[i][j];
} else {
if (i==0 && j == 0) {
ans[i][j] = min(ans[i][j+1], ans[i+1][j])+1;
} else {
int m_int = min(ans[i][j+1], ans[i+1][j])+1;
if (ans[i][j] != -1) {
ans[i][j] = min(m_int, ans[i][j]);
} else {
ans[i][j] = m_int;
}
}
}
}
}
}
return ans;
}
};
submission
Runtime: 208 ms, faster than 39.29% of C++ online submissions for 01 Matrix. Memory Usage: 18.2 MB, less than 100.00% of C++ online submissions for 01 Matrix. Next challenges:
反思
这个判断+1,-1的这么多,写着写着我都晕了。应该有更好的方式。标签里有BFS,有DFS,但是如果用搜索的话效率应该比较低?感觉会进行很多重复的计算。
18-line C++ DP Solution, O(n), Easy to Understand 看这个写法我意识到从上往下的时候可以检查上下左右,标记出无法直接计算距离的,然后从下往上遍历的时候只修改这些还没计算的格子。
从上往下时标记出来的从下往上时可以跳过不看。