An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535).
Given a coordinate (sr, sc) representing the starting pixel (row and column) of the flood fill, and a pixel value newColor, "flood fill" the image.
To perform a "flood fill", consider the starting pixel, plus any pixels connected 4-directionally to the starting pixel of the same color as the starting pixel, plus any pixels connected 4-directionally to those pixels (also with the same color as the starting pixel), and so on. Replace the color of all of the aforementioned pixels with the newColor.
At the end, return the modified image.
Example 1:
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]] Explanation: From the center of the image (with position (sr, sc) = (1, 1)), all pixels connected by a path of the same color as the starting pixel are colored with the new color. Note the bottom corner is not colored 2, because it is not 4-directionally connected to the starting pixel.
Note:
- The length of
imageandimage[0]will be in the range[1, 50]. - The given starting pixel will satisfy
0 <= sr < image.lengthand0 <= sc < image[0].length. - The value of each color in
image[i][j]andnewColorwill be an integer in[0, 65535].
這道題給了一個用二維數組表示的圖像,不同的數字代表不同的顏色,給了一個起始點坐標,還有一個新的顏色,讓我們把起始點的顏色以及其相鄰的同樣的顏色都換成新的顏色。實際上就是一個找相同區間的題,可以用 BFS 或者 DFS 來做。先來看 BFS 的解法,使用一個隊列 queue 來輔助,首先將給定點放入隊列中,然后進行 while 循環,條件是 queue 不為空,然后進行類似層序遍歷的方法,取出隊首元素,將其賦值為新的顏色,然后遍歷周圍四個點,如果不越界,且周圍的顏色跟起始顏色相同的話,將位置加入隊列中,參見代碼如下:
解法一:
class Solution { public: vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) { int m = image.size(), n = image[0].size(), color = image[sr][sc]; vector<vector<int>> res = image; vector<vector<int>> dirs{{0,-1},{-1,0},{0,1},{1,0}}; queue<pair<int, int>> q{{{sr, sc}}}; while (!q.empty()) { int len = q.size(); for (int i = 0; i < len; ++i) { auto t = q.front(); q.pop(); res[t.first][t.second] = newColor; for (auto dir : dirs) { int x = t.first + dir[0], y = t.second + dir[1]; if (x < 0 || x >= m || y < 0 || y >= n || res[x][y] != color) continue; q.push({x, y}); } } } return res; } };
DFS 的寫法相對簡潔一些,首先判斷如果給定位置的顏色跟新的顏色相同的話,直接返回,否則就對給定位置調用遞歸函數。在遞歸函數中,如果越界或者當前顏色跟起始顏色不同,直接返回。否則就給當前位置賦上新的顏色,然后對周圍四個點繼續調用遞歸函數,參見代碼如下:
解法二:
class Solution { public: vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) { if (image[sr][sc] == newColor) return image; helper(image, sr, sc, image[sr][sc], newColor); return image; } void helper(vector<vector<int>>& image, int i, int j, int color, int newColor) { int m = image.size(), n = image[0].size(); if (i < 0 || i >= m || j < 0 || j >= n || image[i][j] != color) return; image[i][j] = newColor; helper(image, i + 1, j, color, newColor); helper(image, i, j + 1, color, newColor); helper(image, i - 1, j, color, newColor); helper(image, i, j - 1, color, newColor); } };
Github 同步地址:
https://github.com/grandyang/leetcode/issues/733
類似題目:
參考資料:
https://leetcode.com/problems/flood-fill/
https://leetcode.com/problems/flood-fill/discuss/109584/java-9-liner-dfs
