LeetCode 733: 图像渲染 flood-fill

简介: 题目:有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535).给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newColor,让你重新上色这幅图像。

题目:

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

An image is represented by a 2-D array of integers, each integer representing the pixel value of the image (from 0 to 65535).

给你一个坐标 (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.

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

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.

示例 1:

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

注意:

  • imageimage[0] 的长度在范围 [1, 50] 内。
  • 给出的初始点将满足 0 <= sr < image.length0 <= 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);
            }
        }
    }
}
目录
相关文章
|
7月前
|
机器学习/深度学习
leetcode-48:旋转图像
leetcode-48:旋转图像
48 0
|
2月前
|
机器学习/深度学习
Leetcode第48题(旋转图像)
这篇文章介绍了LeetCode第48题“旋转图像”的解题方法,通过原地修改二维矩阵实现图像的顺时针旋转90度。
29 0
Leetcode第48题(旋转图像)
|
4月前
|
存储 算法
LeetCode第48题旋转图像
LeetCode第48题"旋转图像"的解题方法,通过两次翻转操作——先水平翻转再对角线翻转,实现了原地旋转矩阵的效果。
LeetCode第48题旋转图像
|
6月前
|
存储 机器学习/深度学习 算法
python 五种算法转置后翻转、层次旋转、递归分块、一次性旋转、环状替换 实现旋转图像【力扣题48】
python 五种算法转置后翻转、层次旋转、递归分块、一次性旋转、环状替换 实现旋转图像【力扣题48】
|
6月前
|
机器学习/深度学习 存储
力扣经典150题第三十六题:旋转图像
力扣经典150题第三十六题:旋转图像
36 0
【Leetcode -733.图像渲染 -744.寻找比目标字母大的最小字母】
【Leetcode -733.图像渲染 -744.寻找比目标字母大的最小字母】
39 0
|
7月前
|
机器学习/深度学习
leetcode代码记录(旋转图像
leetcode代码记录(旋转图像
43 0
|
7月前
leetcode-733:图像渲染
leetcode-733:图像渲染
34 0
|
7月前
|
Go
golang力扣leetcode 48.旋转图像
golang力扣leetcode 48.旋转图像
38 0
|
机器学习/深度学习 Java
48. 旋转图像 --力扣 --JAVA
​ 给定一个 n × n 的二维矩阵 matrix 表示一个图像。请你将图像顺时针旋转 90 度。 你必须在 原地 旋转图像,这意味着你需要直接修改输入的二维矩阵。请不要 使用另一个矩阵来旋转图像。 ​
54 0