题目
给你一个大小为 m x n 的整数矩阵 grid ,表示一个网格。另给你三个整数 row、col 和 color 。网格中的每个值表示该位置处的网格块的颜色。
两个网格块属于同一 连通分量 需满足下述全部条件:
两个网格块颜色相同 在上、下、左、右任意一个方向上相邻 连通分量的边界 是指连通分量中满足下述条件之一的所有网格块:
在上、下、左、右四个方向上与不属于同一连通分量的网格块相邻 在网格的边界上(第一行/列或最后一行/列) 请你使用指定颜色 color 为所有包含网格块 grid[row][col] 的 连通分量的边界 进行着色,并返回最终的网格 grid 。
示例1
输入: grid = [[1,1],[1,2]], row = 0, col = 0, color = 3
输出: [[3,3],[3,2]]
示例2
输入: grid = [[1,2,2],[2,3,2]], row = 0, col = 1, color = 3
输出: [[1,3,3],[2,3,3]]
自然语言描述题目
从起点[row,col]向[row,col]上下左右4个方向,找到若有与grid[row][col]相同的值;这些值在二维数组中组成一个区域,将区域的边界,染成color色;
解题思路
DFS
** 第一步:深度优先遍历**
假设grid[row][col]位置值为x;通过深度优先遍历,从[row,col]出发,向上下左右4个方向寻找,如果任意方向值为x,再以此处为起点向上下左右4个位置寻找是否有x;直到所有点上下左右都不为x;DFS结束;将这部分改变为'-';
问题1:
为什么将x改为'-',而不是将x改为color?
原因1:题目要求找边界,将x直接改变为color;二维数组中grid或许已经有color这个颜色,或者正好在这个【真正的】区域相邻,如果将x染色成x可能会引起【区域】增大; 原因2:color可能和x相同,找不到真正的【区域】
第二步:找边界
边界是什么?
是不是当前位置的上下左右最少有1个不是与自己相同的颜色?
反之,什么不是边界?
即当前位置的上下左右都是自己相同的颜色是吧;
枚举二维数组;二维数组中 '-'的上下左右都为'-'将此处的'-'修改为原有值;
这里需要原有值,那原有值在哪里呢?DBF的时候已经给修改了,那可不可以在修改前把修改的值放在map中呢,毕竟后续可能会用到这个值。不是吗
第三步:边界染色
再次枚举二维数组,将所有'-'染成color即可
动态图
代码
代码长是长了点,但是方便理解
var colorBorder = function (grid, row, col, color) {
const t = grid[row][col]
const m = grid.length
const n = grid[0].length
let key = '-'
const map = new Map()
map.set(`${row},${col}`, grid[row][col])
// 染色
grid[row][col] = key
helper(row, col)
const list = []
for (let i = 0; i < m; i++) {
list[i] = []
for (let j = 0; j < n; j++) {
list[i][j] = grid[i][j]
}
}
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === key) {
// 上下左右都是key,将此位置数据还原
let num = 0
if (i - 1 >= 0 && list[i - 1][j] === key) num++
if (i + 1 < m && list[i + 1][j] === key) num++
if (j - 1 >= 0 && list[i][j - 1] === key) num++
if (j + 1 < n && list[i][j + 1] === key) num++
if (num === 4) {
//console.log('map.get(`${i},${j}`)',map.get(`${i},${j}`))
grid[i][j] = map.get(`${i},${j}`)
}
}
}
}
//console.log('grid',grid)
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] === key) {
grid[i][j] = color
}
}
}
// console.log('grid',grid)
return grid
function helper(i, j) {
const r = [0, 0, 1, -1]
const c = [-1, 1, 0, 0]
for (let k = 0; k < 4; k++) {
const x = r[k] + i
const y = c[k] + j
if (x >= 0 && y >= 0 && x < m && y < n && grid[x][y] === t) {
map.set(`${x},${y}`, grid[x][y])
grid[x][y] = key
helper(x, y)
}
}
}
}