題目:
在這篇文章中,我們來探討 LeetCode 第 733 題 Flood Fill。這是一道圖形處理的問題,與填充演演算法有關,類似於繪圖軟體中使用「油漆桶」工具填充某個區域的操作。
給定一個表示圖像的 2D 整數矩陣 image
,其中 image[i][j]
代表像素值,還有三個整數 sr
, sc
和 newColor
,分別代表起始點的行坐標、列坐標,以及我們要填充的顏色。當你從 image[sr][sc]
開始填充時,會將與此點相鄰且顏色相同的點一併填充,直到不能再擴展。最終回傳修改後的圖像。
範例:
Input: image = [[1,1,1],[1,1,0],[1,0,1]], sr = 1, sc = 1, newColor = 2
Output: [[2,2,2],[2,2,0],[2,0,1]]
針對該點的值,且上下左右鄰居也都是該數值的話,就進行填充,這邊使用DFS遞迴的方式來進行填充。
實作:
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
int curr = image[sr][sc];
if (curr != color)
dfs(image, sr, sc, curr, color);
return image;
}
private:
void dfs(vector<vector<int>>& image, int sr, int sc, int color, int newColor) {
if (image[sr][sc] != color) {
return;
}
image[sr][sc] = newColor;
// up
if (sr-1 >= 0)
dfs(image, sr-1, sc, color, newColor);
// down
if (sr+1 < image.size())
dfs(image, sr+1, sc, color, newColor);
// left
if (sc-1 >= 0)
dfs(image, sr, sc-1, color, newColor);
// right
if (sc+1 < image[0].size())
dfs(image, sr, sc+1, color, newColor);
}
};
這邊練習 BFS 的方式,在之前 Tree 的題目已經練習了 BFS 要搭配 queue,所以很自然的就寫出 BFS 的雛型了,
接著在將像素加入 queue 之前,先檢查它是否符合條件(顏色與 color 一致)。這樣可以避免重複處理已經變更過顏色的像素。
class Solution {
public:
vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int color) {
int curr = image[sr][sc];
if (curr != color)
bfs(image, sr, sc, curr, color);
return image;
}
private:
void bfs(vector<vector<int>>& image, int sr, int sc, int color, int newColor) {
queue<tuple<int, int>> queue;
queue.push({sr, sc});
while (!queue.empty()) {
auto [r, c] = queue.front();
queue.pop();
if (image[r][c] != color) {
continue;
}
image[r][c] = newColor;
// up
if (r-1 >= 0 && image[r-1][c] == color)
queue.push({r-1, c});
// down
if (r+1 < image.size() && image[r+1][c] == color)
queue.push({r+1, c});
// left
if (c-1 >= 0 && image[r][c-1] == color)
queue.push({r, c-1});
// right
if (c+1 < image[0].size() && image[r][c+1] == color)
queue.push({r, c+1});
}
}
};