542. 01 Matrix

更新 發佈閱讀 8 分鐘
https://leetcode.com/problems/01-matrix?envType=problem-list-v2&envId=rabvlt31

熊熊發現最近我好像特愛暴力法...這題我的解法就是暴力破解,沒什麼含金量,程式碼又臭又長,beat 5%的 runtime and memory,昏了都。

class Solution {
public:
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {
int m = mat.size();
int n = mat[0].size();
vector ans(m, vector<int>(n, std::numeric_limits<int>::max()));

for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(mat[i][j] == 0) {
ans[i][j] = 0;
}
}
}

for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
if(ans[i][j] == 0) {
updateSurround(ans, i, j, m, n);
}

}
}

return ans;
}
void updateSurround(vector<vector<int>>& ans, int x, int y, int& m, int& n) {

if(x - 1 >= 0) {
if(ans[x-1][y] > ans[x][y] + 1) {
ans[x-1][y] = ans[x][y] + 1;
updateSurround(ans, x-1, y, m, n);
}
}

if(x + 1 < m) {
if(ans[x+1][y] > ans[x][y] + 1) {
ans[x+1][y] = ans[x][y] + 1;
updateSurround(ans, x+1, y, m, n);
}
}

if(y - 1 >= 0) {
if(ans[x][y-1] > ans[x][y] + 1) {
ans[x][y-1] = ans[x][y] + 1;
updateSurround(ans, x, y-1, m, n);
}
}

if(y + 1 < n) {
if(ans[x][y+1] > ans[x][y] + 1) {
ans[x][y+1] = ans[x][y] + 1;
updateSurround(ans, x, y+1, m, n);
}
}
}
};

當然純純的暴力法是過不了的,會 TLE。我這邊的做法是要先把所有 0 填進去,再來暴力法會減少很多時間。針對每個是 0 的 cell 擴展更新。

Best Solution

class Solution {
public:
vector<int> DIR = {0, 1, 0, -1, 0};
vector<vector<int>> updateMatrix(vector<vector<int>>& mat) {

int m = mat.size(), n = mat[0].size();

queue<pair<int, int>> q;
for (int r = 0; r < m; ++r)
for (int c = 0; c < n; ++c)
if (mat[r][c] == 0) q.emplace(r, c);
else mat[r][c] = -1; // Marked as not processed yet!

while (!q.empty()) {
auto [r, c] = q.front(); q.pop();
for (int i = 0; i < 4; ++i) {
int nr = r + DIR[i], nc = c + DIR[i+1];
if (nr < 0 || nr == m || nc < 0 || nc == n || mat[nr][nc] != -1) continue;
mat[nr][nc] = mat[r][c] + 1;
q.emplace(nr, nc);
}
}
return mat;
}
};

優雅!!真是太優雅了!!這個 solution 用了 queue 來 maintain 更新的過程,某種程度上來講是 BFS,保證每個 cell 被 遍歷到的時候更新都會直接是答案,原因就是離 0 較近的 cell 會先被遍歷到!!聰明太聰明了。

這個 solution 讓我複習了 queue 的用法。除了演算法很聰明外,這個作者也用了 emplace 來取代一些不必要的變數複製與移動等。非常聰明的做法,甚至 memory 不用重新宣告。

留言
avatar-img
星星在晚上的時候不睡覺
0會員
13內容數
資工系的勞碌人生
2026/01/04
https://leetcode.com/problems/four-divisors?envType=daily-question&envId=2026-01-04 找因數並且做相加的題目。找因數是我很害怕的類型,因為我對輾轉相除法之類的真的是永遠背不起來,每次都考過就忘,遇到這題我的知識庫裡就
2026/01/04
https://leetcode.com/problems/four-divisors?envType=daily-question&envId=2026-01-04 找因數並且做相加的題目。找因數是我很害怕的類型,因為我對輾轉相除法之類的真的是永遠背不起來,每次都考過就忘,遇到這題我的知識庫裡就
2026/01/04
https://leetcode.com/problems/number-of-ways-to-paint-n-3-grid?envType=daily-question&envId=2026-01-03 第一個在 leetcode 寫到的 Hard 題目,我覺得這題不算是很難想出解法的類型,他難
2026/01/04
https://leetcode.com/problems/number-of-ways-to-paint-n-3-grid?envType=daily-question&envId=2026-01-03 第一個在 leetcode 寫到的 Hard 題目,我覺得這題不算是很難想出解法的類型,他難
2026/01/02
https://leetcode.com/problems/magic-squares-in-grid?envType=daily-question&envId=2025-12-30 這題是乍看之下有點難的 Medium,實際上在 Medium 難度中應該算中下(個人觀點)。 看到題目的當下,便
2026/01/02
https://leetcode.com/problems/magic-squares-in-grid?envType=daily-question&envId=2025-12-30 這題是乍看之下有點難的 Medium,實際上在 Medium 難度中應該算中下(個人觀點)。 看到題目的當下,便
看更多