有一幅以二維整數數組表示的圖畫,每個整數表示該圖畫的像素值大小,數值在 0 到 65535 之間。java
An image
is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535).python
給你一個座標 (sr, sc) 表示圖像渲染開始的像素值(行 ,列)和一個新的顏色值 newColor,讓你從新上色這幅圖像。數組
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.數據結構
爲了完成上色工做,從初始座標開始,記錄初始座標的上下左右四個方向上像素值與初始座標相同的相連像素點,接着再記錄這四個方向上符合條件的像素點與他們對應四個方向上像素值與初始座標相同的相連像素點,……,重複該過程。將全部有記錄的像素點的顏色值改成新的顏色值。ide
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.函數
最後返回通過上色渲染後的圖像。spa
At the end, return the modified image.指針
示例 1:code
輸入: image = [[1,1,1],[1,1,0],[1,0,1]] sr = 1, sc = 1, newColor = 2 輸出: [[2,2,2],[2,2,0],[2,0,1]] 解析: 在圖像的正中間,(座標(sr,sc)=(1,1)), 在路徑上全部符合條件的像素點的顏色都被更改爲2。 注意,右下角的像素沒有更改成2, 由於它不是在上下左右四個方向上與初始點相連的像素點。
注意:orm
image
和 image[0]
的長度在範圍 [1, 50]
內。0 <= sr < image.length
和 0 <= sc < image[0].length
。image[i][j]
和 newColor
表示的顏色值在範圍 [0, 65535]
內。Note:
The length of image
and image[0]
will be in the range [1, 50]
.
The given starting pixel will satisfy 0 <= sr < image.length
and 0 <= sc < image[0].length
.
The value of each color in image[i][j]
and newColor
will be an integer in [0, 65535]
.
與01矩陣 相似,在圖的數據結構內找到全部舊的像素點改爲新的新素值。無非是圖的遍歷,BFS和DFS。
就這道題而言,不涉及路徑長度,明顯DFS深度優先遍歷更適合。由於BFS廣度優先遍歷須要記錄每一個相鄰符合要求的位置,而且不能添加劇復的點。 DFS能夠用棧或遞歸實現,若是用棧來解雖然比遞歸更好理解一些,可是每次依然要存儲每一個點的索引位置,而且出入棧也會消耗時間。因此這道題的最優解應該是用遞歸實現的深度優先遍歷解題。
DFS(Java):
class Solution { private boolean withinBounds(int[][] img, int i, int j) {//判斷指針是否溢出 return (i < img.length && i >= 0) && (j < img[0].length && j >= 0); } private void floodFillProcess(int[][] img, int sr, int sc, int oc, int nc) { if (withinBounds(img, sr, sc) && img[sr][sc] == oc) {//指針不溢出且像素值爲舊值時 img[sr][sc] = nc;//改成新值 floodFillProcess(img, sr - 1, sc, oc, nc);//遞歸上下左右四個點 floodFillProcess(img, sr + 1, sc, oc, nc); floodFillProcess(img, sr, sc - 1, oc, nc); floodFillProcess(img, sr, sc + 1, oc, nc); } } public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { int oc = image[sr][sc]; if (newColor == oc) return image; floodFillProcess(image, sr, sc, oc, newColor); return image; } }
DFS(Python):
class Solution: def floodFill(self, image: List[List[int]], sr: int, sc: int, newColor: int) -> List[List[int]]: oldColor = image[sr][sc] if oldColor == newColor: return image self.dfs(image, sr, sc, oldColor, newColor) return image def dfs(self, image: List[List[int]], sr: int, sc: int, oldColor: int, newColor: int): if image[sr][sc] == oldColor: image[sr][sc] = newColor if sr-1 >= 0:#先判斷是否溢出再決定是否遞歸 self.dfs(image, sr-1, sc, oldColor, newColor) if sr+1 < len(image): self.dfs(image, sr+1, sc, oldColor, newColor) if sc-1 >= 0: self.dfs(image, sr, sc-1, oldColor, newColor) if sc+1 < len(image[0]): self.dfs(image, sr, sc+1, oldColor, newColor)
附:
BFS深度優先遍歷(Java):
class Solution { public int[][] floodFill(int[][] image, int sr, int sc, int newColor) { int oldColor = image[sr][sc]; if (oldColor == newColor) return image;//舊像素值與新像素值相等時,無需修改 int rows = image.length; int columns = image[0].length; bfs(image, sr * columns + sc, rows, columns, newColor, oldColor);//進入BFS輔助函數 return image; } private void bfs(int[][] img, int loc, int row, int column, int nc, int oc) { Set<Integer> set = new LinkedHashSet<>(); //set(),避免添加劇復點 Queue<Integer> queue = new LinkedList<>(); queue.add(loc);//隊列加入第一個初始點,記錄點索引的方式是x*column+y, while (!queue.isEmpty()) { int tmp = queue.poll(); int r = tmp / column, c = tmp % column;//拆解位置 if (img[r][c] == oc && !set.contains(tmp)) {//像素值爲舊值,而且該點未被計算過 img[r][c] = nc;//改成新值 set.add(tmp); if (r + 1 < row) if (img[r + 1][c] == oc) queue.add((r + 1) * column + c); if (r - 1 >= 0) if (img[r - 1][c] == oc) queue.add((r - 1) * column + c); if (c + 1 < column) if (img[r][c + 1] == oc) queue.add(r * column + c + 1); if (c - 1 >= 0) if (img[r][c - 1] == oc) queue.add(r * column + c - 1); } } } }