1. 程式人生 > >733. Flood Fill(python+cpp)

733. Flood Fill(python+cpp)

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 image and image[0] will be in the range [1, 50]. The given starting pixel will satisfy0 <= sr < image.length and 0 <= sc <image[0].length. The value of each color inimage[i][j] and newColor will be an integer in[0, 65535].

解釋: dfs,思想很簡單,對原始的image實現一個dfs,繼續進行dfs的條件是: 1.下一個元素在範圍內 2.下一個元素與當前元素的顏色相同 有一個trick就是:當新的顏色和當前正在處理的位置的顏色相同時,這時候將會有一個無限迴圈(因為此時image[row][col]==orig_color

永遠成立)。所以如果新的顏色和當前正在處理的位置的顏色相同,我們什麼都不需要做,只需要返回image即可。 深度優先一個很重要的問題就是訪問過的資料需要被有效標記,避免二次訪問,當newcolor跟原始資料一致的時候,改變原始資料並不能產生想要的標記效果,導致無法跳出遞迴的迴圈。(當新顏色和舊顏色不一樣時,改變了顏色之後會跳出迴圈(主要是image[row][col]!=orig_color的作用),但是一樣時,就不會跳出迴圈了)。 python程式碼:

class Solution(object):
    def floodFill(self, image, sr, sc, newColor):
        """
        :type image: List[List[int]]
        :type sr: int
        :type sc: int
        :type newColor: int
        :rtype: List[List[int]]
        """
        if not image:
            return image
        rows,cols,orig_color=len(image),len(image[0]),image[sr][sc]
        def dfs(row,col):
            if (not (0<=row<rows and 0<=col<cols) or image[row][col]!=orig_color):
                return
            image[row][col]=newColor
            [dfs(row+x,col+y) for x,y in ((0,1),(1,0),(0,-1),(-1,0)) ]
        if orig_color!=newColor:
            dfs(sr,sc)
        return image

c++程式碼:

class Solution {
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
        int ori_color=image[sr][sc];
        if (ori_color!=newColor)
            dfs(sr,sc,image,ori_color,newColor);
        return image;
    
    }
    void dfs(int r,int c,vector<vector<int>>&images,int ori_color,int newColor)
    {
        vector<vector<int>> directions={{0,1},{0,-1},{1,0},{-1,0}};
        int rows=images.size();
        int cols=images[0].size();
        if (r>=rows ||r<0 ||c>=cols ||c<0 or images[r][c]!=ori_color)
            return;
        images[r][c]=newColor;
        for(auto direction:directions)
            dfs(r+direction[0],c+direction[1],images,ori_color,newColor);
    }
};

總結: 對於dfs的問題,已經遍歷過的位置一定要合理標記,這樣就能防止一直搜尋已經搜尋過的地方了。