733. 图像渲染(Python)

题目

难度:★★☆☆☆
类型:几何,深度优先搜索

有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。

给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。

为了完成上色工作,从初始坐标开始,记录初始坐标的上下左右四个方向上像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应四个方向上像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为新的颜色值。

最后返回经过上色渲染后的图像。

注意
image 和 image[0] 的长度在范围 [1, 50] 内。
给出的初始点将满足 0 <= sr < image.length 和 0 <= sc < image[0].length。
image[i][j] 和 newColor 表示的颜色值在范围 [0, 65535]内。

示例

输入:
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,
因为它不是在上下左右四个方向上与初始点相连的像素点。

解答

这道题我们可以用深度优先搜索来实现,首先我们来看一下什么是深度优先搜索。深度优先搜索属于图算法的一种,英文缩写为DFS即Depth First Search.其过程简要来说是对每一个可能的分支路径深入到不能再深入为止,而且每个结点只能访问一次。(来自百度百科)

我们需要另外构建深度优先搜索函数,该函数用于实现对联通域(具有相同颜色的联通区域)内所有像素进行上色。

函数输入输出

该函数的输入与主函数一致,包含一张图像(会原地修改),上色初始点的坐标(sr, sc);函数没有输出,但是会对输入的图像进行操作。

函数实现

该函数的实现依赖于几个重要的变量,我们使用实例变量,这样可以在全局使用,因为所有层次的递归都会用到:

  1. 集合。我们准备一个集合,这是一个全局变量,用来存放已经修改的像素点,从而保证每个结点只遍历一次,避免重复遍历超过最大递归深度;

  2. 颜色。包括修改前的颜色(prev_color)和修改后的颜色(new_color)。

具体操作:

  1. 每次调用函数,首先查看输入点是否在集合内,如果在,则不进行任何操作,否则,将该点处的像素值记录下来;

  2. 将该点处的颜色修改为新颜色。其实该点处的颜色在修改前一定是prev_color,因为我们有如下的递归条件;

  3. 向上下左右四个方向探索,这里需要注意增加下标合法性的判断,如果某一个方向上相邻像素点的颜色是prev_color,说明该像素点在联通域内,那么调用本函数,对该像素点进行上色。

class Solution:
    def floodFill(self, image, sr, sc, newColor):
        self.unicom = set()                 # 存放联通域内遍历过的所有像素
        self.prev_color = image[sr][sc]     # 联通域内要修改的像素的颜色
        self.new_color = newColor           # 新颜色

        def dfs(image, sr, sc):
            if (sr, sc) in self.unicom:
                return

            image[sr][sc] = self.new_color  # 上色
            self.unicom.add((sr, sc))       # 集合中添加记录

            if sr >= 1 and image[sr-1][sc] == self.prev_color:
                dfs(image, sr-1, sc)

            if sr < len(image) - 1 and image[sr+1][sc] == self.prev_color:
                dfs(image, sr+1, sc)

            if sc >= 1 and image[sr][sc-1] == self.prev_color:
                dfs(image, sr, sc-1)

            if sc < len(image[0]) - 1 and image[sr][sc+1] == self.prev_color:
                dfs(image, sr, sc+1)

        dfs(image, sr, sc)
        return image

如有疑问或建议,欢迎评论区留言~

你可能感兴趣的:(733. 图像渲染(Python))