The Image Flood Fill Algorithm (C++)

  • 时间:2020-10-11 15:48:46
  • 分类:网络文摘
  • 阅读:149 次

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 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].

Recursion Flood Fill – Depth First Search

The flood fill algorithm can be done via recursion using the DPS (Depth First Search Algorithm). We can modify the original image in order to mark a pixel that has been flooded. Along the four directions, if the pixel is the same as the origin color, we set it to the target.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
class Solution {
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
        int height = image.size();
        if (height == 0) return image;
        int width = image[0].size();
        if (width == 0) return image;
        int color = image[sr][sc];
        if (color == newColor) return image;
        image[sr][sc] = newColor;
        if ((sr > 0) && (image[sr - 1][sc] == color)) floodFill(image, sr - 1, sc, newColor);
        if ((sc > 0) && (image[sr][sc - 1] == color)) floodFill(image, sr, sc - 1, newColor);
        if ((sr < height - 1)  && (image[sr + 1][sc] == color)) floodFill(image, sr + 1, sc, newColor);
        if ((sc < width - 1) && (image[sr][sc + 1] == color)) floodFill(image, sr, sc + 1, newColor);
        return image;
    }
};
class Solution {
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
        int height = image.size();
        if (height == 0) return image;
        int width = image[0].size();
        if (width == 0) return image;
        int color = image[sr][sc];
        if (color == newColor) return image;
        image[sr][sc] = newColor;
        if ((sr > 0) && (image[sr - 1][sc] == color)) floodFill(image, sr - 1, sc, newColor);
        if ((sc > 0) && (image[sr][sc - 1] == color)) floodFill(image, sr, sc - 1, newColor);
        if ((sr < height - 1)  && (image[sr + 1][sc] == color)) floodFill(image, sr + 1, sc, newColor);
        if ((sc < width - 1) && (image[sr][sc + 1] == color)) floodFill(image, sr, sc + 1, newColor);
        return image;
    }
};

However, the above implementation may still produce stack over flow if the recursion depths is large.

Flood Fill Algorithm with Breadth First Search

We can solve the problem of stack-over-flow by using BFS (Breadth First Search). We maintain a queue with initial node of the start pixel. Every iteration, we de-queue and push possible four directions into the queue.

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
class Solution {
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
        int height = image.size();
        if (height == 0) return image;
        int width = image[0].size();
        if (width == 0) return image;
        int color = image[sr][sc];
        if (color == newColor) return image;
        queue<pair<int, int>> Q;
        Q.push(make_pair(sr, sc));
        while (Q.size() > 0) {
            auto p = Q.front();
            Q.pop();
            int r = p.first;
            int c = p.second;
            image[r][c] = newColor;
            if ((r < height - 1) && (image[r + 1][c] == color)) {
                Q.push(make_pair(r + 1, c));
            }
            if ((r > 0) && (image[r - 1][c] == color)) {
                Q.push(make_pair(r - 1, c));
            }
            if ((c < width - 1) && (image[r][c + 1] == color)) {
                Q.push(make_pair(r, c + 1));
            }
            if ((c > 0) && (image[r][c - 1] == color)) {
                Q.push(make_pair(r, c - 1));
            }        
        }
        return image;
    }
};
class Solution {
public:
    vector<vector<int>> floodFill(vector<vector<int>>& image, int sr, int sc, int newColor) {
        int height = image.size();
        if (height == 0) return image;
        int width = image[0].size();
        if (width == 0) return image;
        int color = image[sr][sc];
        if (color == newColor) return image;
        queue<pair<int, int>> Q;
        Q.push(make_pair(sr, sc));
        while (Q.size() > 0) {
            auto p = Q.front();
            Q.pop();
            int r = p.first;
            int c = p.second;
            image[r][c] = newColor;
            if ((r < height - 1) && (image[r + 1][c] == color)) {
                Q.push(make_pair(r + 1, c));
            }
            if ((r > 0) && (image[r - 1][c] == color)) {
                Q.push(make_pair(r - 1, c));
            }
            if ((c < width - 1) && (image[r][c + 1] == color)) {
                Q.push(make_pair(r, c + 1));
            }
            if ((c > 0) && (image[r][c - 1] == color)) {
                Q.push(make_pair(r, c - 1));
            }        
        }
        return image;
    }
};

As the queue can dynamically grow or shrink, there is no risks of overflowing the stack.

–EOF (The Ultimate Computing & Technology Blog) —

推荐阅读:
采蘑菇数学题  小红可能在什么时间去摘西红柿  称螺丝的数学题  一乘二分之一加二乘三分之一加…九十九乘一百分之一加一百乘一百零一分之一等于多少?求答题过程和答案。  为什么所有剩下的钱加起来是51元?  十二个乒乓球特征相同,其中只有一个重量异常  某银行有两种储蓄计划——单利和复利的问题  大院里养了三种动物。每只小山羊戴3个铃铛,每只狗戴1个铃铛  某本书正文所标注的页码共用了2989个阿拉伯数字,问这本书的正文一共有多少页?  有两棵古槐树,500年前有个学者说 
评论列表
添加评论