终端产品在进行一项噪音监测实验。若将空实验室平面图视作一个N*M的二维矩阵(左上角为[0,0])。工作人员在实验室内设置了若干噪音源,并以[噪音源所在行,噪音源所在列,噪音值]的形式记录于二维数组noise中。
噪音沿相邻8个方向传播,在传播过程中,噪音值(单位为分贝)逐级递减1分贝,直至分贝削弱至1(即噪音源覆盖区域边缘噪音分贝为1);
若同一格被多个噪音源的噪音覆盖,检测结果不叠加,仅保留较大的噪音值(噪音源所在格也可能被其他噪音源的噪声传播所覆盖)。
在所有噪音源开启且持续传播情况稳定后,请监测每格噪音分贝数并返回他们的总和。
注意:
除噪音源以外的所有格初始值为0分贝;
不考虑墙面反射。
示例1:
输入:n=5,m=6,noise=[[3,4,3],[1,1,4]]
输出:63
DFS或者直接计算
/**
* DFS
*
* @param n
* @param m
* @param noise
* @return
*/
public int spreadNoise(int n, int m, int[][] noise) {
if (noise.length == 0) {
return 0;
}
// 记录路径
int[][] grids = new int[n][m];
// 记录结果
int sum = 0;
for (int[] currentNoise : noise) {
dfs(currentNoise[0], currentNoise[1], currentNoise[2], grids);
}
return getSum(n, m, sum, grids);
}
/**
* 计算结果
*
* @param n
* @param m
* @param sum
* @param grids
* @return
*/
private int getSum(int n, int m, int sum, int[][] grids) {
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
if (grids[i][j] > 0) {
sum += grids[i][j];
}
}
}
return sum;
}
private void dfs(int row, int col, int val, int[][] grids) {
// 循环结束条件
if (row >= grids.length || col >= grids[1].length || val == 0) {
return;
}
if (row < 0 || col < 0 || grids[row][col] >= val) {
return;
}
// 记录值
grids[row][col] = val;
// 沿8个方向扩散
dfs(row + 1, col, val - 1, grids);
dfs(row - 1, col, val - 1, grids);
dfs(row, col + 1, val - 1, grids);
dfs(row, col - 1, val - 1, grids);
dfs(row + 1, col + 1, val - 1, grids);
dfs(row + 1, col - 1, val - 1, grids);
dfs(row - 1, col + 1, val - 1, grids);
dfs(row - 1, col - 1, val - 1, grids);
}
/**
* 直接遍历每个格子,计算噪音值即可
*
* @param n
* @param m
* @param noise
* @return
*/
public int spreadNoise2(int n, int m, int[][] noise) {
int[][] grids = new int[n][m];
int sum = 0;
// 记录步长
int len;
for (int i = 0; i < n; i++) {
for (int j = 0; j < m; j++) {
for (int k = 0; k < noise.length; k++) {
// 行步长
int rowLen = Math.abs(i - noise[k][0]);
// 列步长
int colLen = Math.abs(j - noise[k][1]);
// 与噪音源的最大步长
len = Math.max(rowLen, colLen);
// 得到最大噪音
grids[i][j] = Math.max(grids[i][j], Math.max(noise[k][2] - len, 0));
}
sum += grids[i][j];
}
}
return sum;
}
类似
https://leetcode-cn.com/problems/max-area-of-island/
class Solution_695 {
int[][] grid;
public int maxAreaOfIsland(int[][] grid) {
if (grid.length == 0) {
return 0;
}
this.grid = grid;
// 记录结果
int max = 0;
for (int i = 0; i < grid.length; i++) {
for (int j = 0; j < grid[0].length; j++) {
max = Math.max(max, dfs(i, j));
}
}
return max;
}
private int dfs(int row, int col) {
// 循环结束条件
if (row < 0 || col < 0 ||
row >= grid.length || col >= grid[0].length || grid[row][col] == 0) {
return 0;
}
// 下沉,代表已经访问了
grid[row][col]--;
// 初始化最小连通区域
int areas = 1;
areas += dfs(row - 1, col); // 上
areas += dfs(row + 1, col); // 下
areas += dfs(row, col - 1); // 左
areas += dfs(row, col + 1); // 右
return areas;
}
}