图像渲染
难度:
标签:
题目描述
有一幅以 m x n
的二维整数数组表示的图画 image
,其中 image[i][j]
表示该图画的像素值大小。
你也被给予三个整数 sr
, sc
和 newColor
。你应该从像素 image[sr][sc]
开始对图像进行 上色填充 。
为了完成 上色工作 ,从初始像素开始,记录初始坐标的 上下左右四个方向上 像素值与初始坐标相同的相连像素点,接着再记录这四个方向上符合条件的像素点与他们对应 四个方向上 像素值与初始坐标相同的相连像素点,……,重复该过程。将所有有记录的像素点的颜色值改为 newColor
。
最后返回 经过上色渲染后的图像 。
示例 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,因为它不是在上下左右四个方向上与初始点相连的像素点。
示例 2:
输入: image = [[0,0,0],[0,0,0]], sr = 0, sc = 0, newColor = 2 输出: [[2,2,2],[2,2,2]]
提示:
m == image.length
n == image[i].length
1 <= m, n <= 50
0 <= image[i][j], newColor < 216
0 <= sr < m
0 <= sc < n
代码结果
运行时间: 19 ms, 内存: 16.2 MB
/*
* 思路:
* 1. 获取初始像素的颜色 oldColor。
* 2. 如果 oldColor 与 newColor 相同,直接返回原图像。
* 3. 使用深度优先搜索(DFS)从初始像素开始上色,
* 每次递归处理上下左右四个方向的像素。
* 使用 Java Stream API 的方式实现较为复杂,不适合处理这种需要递归的图像处理问题。
*/
import java.util.stream.IntStream;
public class Solution {
public int[][] floodFill(int[][] image, int sr, int sc, int newColor) {
int oldColor = image[sr][sc];
if (oldColor != newColor) {
fill(image, sr, sc, oldColor, newColor);
}
return image;
}
private void fill(int[][] image, int sr, int sc, int oldColor, int newColor) {
if (sr < 0 || sr >= image.length || sc < 0 || sc >= image[0].length) return;
if (image[sr][sc] != oldColor) return;
image[sr][sc] = newColor;
IntStream.of(-1, 1).forEach(i -> {
fill(image, sr + i, sc, oldColor, newColor); // 上下
fill(image, sr, sc + i, oldColor, newColor); // 左右
});
}
}
解释
方法:
该题解使用深度优先搜索(DFS)的思路,具体步骤如下:
1. 定义方向数组 directions,表示上下左右四个方向。
2. 记录初始点的颜色为 changed_color。
3. 如果初始点的颜色与新颜色相同,直接返回原图像。
4. 将初始点坐标压入栈 stack 中。
5. 当栈不为空时,循环执行以下操作:
- 弹出栈顶元素 curr,获取当前点的坐标 (row, col)。
- 将当前点的颜色更改为新颜色。
- 遍历四个方向:
- 计算新坐标 (newrow, newcol)。
- 如果新坐标在图像范围内且颜色与初始点相同,将新坐标压入栈中。
6. 返回更改后的图像。
时间复杂度:
O(m*n)
空间复杂度:
O(m*n)
代码细节讲解
🦆
为什么在这个算法中选择使用深度优先搜索(DFS)而不是广度优先搜索(BFS)?
▷🦆
在判断新坐标是否在图像范围内时,代码中的检查逻辑是否有重复计算的可能,能否优化?
▷🦆
为何在栈为空前持续处理,而不是检查某种条件后退出循环?
▷🦆
代码中直接修改了输入的`image`数组,这种做法是否安全,或者是否有不修改原输入的方案?
▷相关问题
岛屿的周长
给定一个 row x col
的二维网格地图 grid
,其中:grid[i][j] = 1
表示陆地, grid[i][j] = 0
表示水域。
网格中的格子 水平和垂直 方向相连(对角线方向不相连)。整个网格被水完全包围,但其中恰好有一个岛屿(或者说,一个或多个表示陆地的格子相连组成的岛屿)。
岛屿中没有“湖”(“湖” 指水域在岛屿内部且不和岛屿周围的水相连)。格子是边长为 1 的正方形。网格为长方形,且宽度和高度均不超过 100 。计算这个岛屿的周长。
示例 1:
输入:grid = [[0,1,0,0],[1,1,1,0],[0,1,0,0],[1,1,0,0]] 输出:16 解释:它的周长是上面图片中的 16 个黄色的边
示例 2:
输入:grid = [[1]] 输出:4
示例 3:
输入:grid = [[1,0]] 输出:4
提示:
row == grid.length
col == grid[i].length
1 <= row, col <= 100
grid[i][j]
为0
或1