题目:

有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 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);
}
}
}
}

LeetCode 733: 图像渲染 flood-fill的更多相关文章

  1. Java实现 LeetCode 733 图像渲染(DFS)

    733. 图像渲染 有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间. 给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的 ...

  2. [Swift]LeetCode733. 图像渲染 | Flood Fill

    An image is represented by a 2-D array of integers, each integer representing the pixel value of the ...

  3. Leetcode之深度优先搜索(DFS)专题-733. 图像渲染(Flood Fill)

    Leetcode之深度优先搜索(DFS)专题-733. 图像渲染(Flood Fill) 深度优先搜索的解题详细介绍,点击 有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 ...

  4. 【LeetCode】733. Flood Fill 解题报告(Python)

    作者: 负雪明烛 id: fuxuemingzhu 个人博客: http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 方法一:DFS 方法二:BFS 日期 题目地址:ht ...

  5. LN : leetcode 733 Flood Fill

    lc 733 Flood Fill 733 Flood Fill An image is represented by a 2-D array of integers, each integer re ...

  6. [LeetCode&Python] Problem 733. Flood Fill

    An image is represented by a 2-D array of integers, each integer representing the pixel value of the ...

  7. Leetcode733.Flood Fill图像渲染

    有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间. 给你一个坐标 (sr, sc) 表示图像渲染开始的像素值(行 ,列)和一个新的颜色值 newCol ...

  8. [LeetCode] Flood Fill 洪水填充

    An image is represented by a 2-D array of integers, each integer representing the pixel value of the ...

  9. 【Leetcode_easy】733. Flood Fill

    problem 733. Flood Fill 题意:图像处理中的泛洪填充算法,常见的有四邻域像素填充法.八邻域像素填充法.基于扫描线的像素填充法,实现方法分为递归与非递归(基于栈). 泛洪填充算法原 ...

随机推荐

  1. hibernate的对象/关系映射结果为空,exists查不到值的问题-20190823

    1: hibernate的对象/关系映射 情景:在使用@onetotone/@manytonone时关联结果为空 原因:在使用这个注解的时候,默认的时crossjoin(交叉连接),在进行查询时以及排 ...

  2. 用sticky.js实现头部导航栏固定

    在页面中,如果页面长度过大,滑动页面时,头部导航栏则会跟着划走. 我的头部导航栏代码为: <div class="headbar"> <center class= ...

  3. Spring中ApplicationListener的使用

    背景 ApplicationListener是Spring事件机制的一部分,与抽象类ApplicationEvent类配合来完成ApplicationContext的事件机制. 如果容器中存在Appl ...

  4. 用友的SPS定义

    基于标准产品的支持服务(Standard Product Support,SPS).主要包括:更新升级(软件补丁更新与产品升级).问题解决(产品问题在线或热线解析).知识转移(用友到客户的知识传递). ...

  5. JDK1.8新特性——使用新的方式遍历集合

    JDK1.8新特性——使用新的方式遍历集合 摘要:本文主要学习了在JDK1.8中新增的遍历集合的方式. 遍历List 方法: default void forEach(Consumer<? su ...

  6. TCP协议的三次握手与四次挥手

    1.数据包说明 1)源端口号(16位):它(连同源主机IP地址)标识源主机的一个应用进程. 2)目标端口号(16位):它(连同源主机IP地址)标识目的主机的一个应用进程.这两个值加上IP报头中的源主机 ...

  7. Spring Boot 之异步执行方法

    前言: 最近的时候遇到一个需求,就是当服务器接到请求并不需要任务执行完成才返回结果,可以立即返回结果,让任务异步的去执行.开始考虑是直接启一个新的线程去执行任务或者把任务提交到一个线程池去执行,这两种 ...

  8. Linux下 vim代码编译器的使用

    首先在命令行模式下输入代码: vim ok.c 创建c文件 如果发现vim没有被安装的话,输入以下代码对vim进行安装: sudo apt install vim 安装完毕之后再输入第一行代码,之后进 ...

  9. itest(爱测试) 4.1.5 发布,开源BUG 跟踪管理 & 敏捷测试管理软件

    v4.1.5下载地址 :itest下载 itest 简介:查看简介 itest 开源敏捷测试管理,testOps 践行者.可按测试包分配测试用例执行,也可建测试迭代(含任务,测试包,BUG)来组织测试 ...

  10. hibernate之主键生成策略

    1. hibernate的主键生成器: generator元素:表示了一个主键生成器,它用来为持久化类实例生成唯一的标识 . 连接数据库的xml hibernate.cfg.xml <?xml ...