这是我参与8月更文挑战的第8天,活动详情查看:8月更文挑战
图像渲染
题目
有一幅以二维整数数组表示的图画,每一个整数表示该图画的像素值大小,数值在 0 到 65535 之间。
给你一个坐标 (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,
因为它不是在上下左右四个方向上与初始点相连的像素点。
题解
题目很长,我读了很久才搞明白要求。在给定点位置的上下左右,并且四个方向的值要和给定点的值相同。这样给定点变成新值后,四个方向的值也要跟着改变。 之后,再以四个方向的点分别作为定点,找各自的上下左右,值相同的,将其变成新值。依次类推。
思路:
题目理清楚了,思路既然也就有了。首先肯定存在对上下左右四个方向的递归过程。
- 新值和原来的值相同,直接返回原数组。
- 不同。从这个点开始向上下左右四个方向依次扩散。四个方向上和中间点的值相同时,就需要将其和中间点一样改成新值。
- 扣边界。在递归过程中,如果中间点的四个方向在最外一圈的,再向外扩散就超界的情况可以直接返回
- 定点值和当前点值不同是不需要改变的。
代码
var floodFill = function (image, sr, sc, newColor) {
let m = image.length, n = image[0].length, oldColor = image[sr][sc]
if (oldColor == newColor) return image
let fill = (i, j) => {
if (i < 0 || j < 0 || i >= m || j >= n || image[i][j] != oldColor) return
image[i][j] = newColor
fill(i + 1, j)
fill(i - 1, j)
fill(i, j + 1)
fill(i, j - 1)
}
fill(sr, sc)
return image
};
岛屿的最大面积
题目
给定一个包含了一些 0 和 1 的非空二维数组 grid 。
一个 岛屿 是由一些相邻的 1 (代表土地) 构成的组合,这里的「相邻」要求两个 1 必须在水平或者竖直方向上相邻。你可以假设 grid 的四个边缘都被 0(代表水)包围着。
找到给定的二维数组中最大的岛屿面积。(如果没有岛屿,则返回面积为 0 。)
示例 1:
[[0,0,1,0,0,0,0,1,0,0,0,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,1,1,0,1,0,0,0,0,0,0,0,0],
[0,1,0,0,1,1,0,0,1,0,1,0,0],
[0,1,0,0,1,1,0,0,1,1,1,0,0],
[0,0,0,0,0,0,0,0,0,0,1,0,0],
[0,0,0,0,0,0,0,1,1,1,0,0,0],
[0,0,0,0,0,0,0,1,1,0,0,0,0]]
对于上面这个给定矩阵应返回 6。注意答案不应该是 11 ,因为岛屿只能包含水平或垂直的四个方向的 1 。
题解
这题和上题,较为类似。上题是给定点,依次向外扩散;而这题是求最多的有多少点四个方向相连。可以通过循环遍历去求,但是在递归过程中我们需要将递归过的点变为0,避免在此循环重复。
遍历:当点为1时,进行递归操作,寻找最大面积。从当前点向上下左右四个方向依次扩散递归。需要注意的还是边界问题(递归终止条件)。除了四个方向不越界之外,当前递归点不为0的情况。
代码
var maxAreaOfIsland = function (grid) {
let m = grid.length, n = grid[0].length, maxArea = 0
const Island = (i, j) => {
if (i < 0 || j < 0 || i >= m || j >= n || grid[i][j] == 0) return 0
grid[i][j] = 0
let max = 1
max += Island(i + 1, j)
max += Island(i - 1, j)
max += Island(i, j - 1)
max += Island(i, j + 1)
return max
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] == 1) {
maxArea = Math.max(maxArea, Island(i, j))
}
}
}
return maxArea
};
题目来源:leetcode