保持城市天际线

保持城市天际线

在二维数组grid中,grid[i][j]代表位于某处的建筑物的高度。 我们被允许增加任何数量(不同建筑物的数量可能不同)的建筑物的高度。高度0也被认为是建筑物。
最后,从新数组的所有四个方向(即顶部,底部,左侧和右侧)观看的“天际线”必须与原始数组的天际线相同。 城市的天际线是从远处观看时,由所有建筑物形成的矩形的外部轮廓。 请看下面的例子。
建筑物高度可以增加的最大总和是多少?

示例

输入: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]
输出: 35
解释: 
The grid is:
[ [3, 0, 8, 4], 
  [2, 4, 5, 7],
  [9, 2, 6, 3],
  [0, 3, 1, 0] ]

从数组竖直方向(即顶部,底部)看“天际线”是:[9, 4, 8, 7]
从水平水平方向(即左侧,右侧)看“天际线”是:[8, 7, 9, 3]

在不影响天际线的情况下对建筑物进行增高后,新数组如下:

gridNew = [ [8, 4, 8, 7],
            [7, 4, 7, 7],
            [9, 4, 8, 7],
            [3, 3, 3, 3] ]

题解

/**
 * @param {number[][]} grid
 * @return {number}
 */
var maxIncreaseKeepingSkyline = function(grid) {
    const nL = grid.length;
    const nT = grid.length; // 题目给定 grid.length = grid[0].length
    let maxL = Array(nL).fill(0);
    let maxT = Array(nT).fill(0);
    for(let i=0; i<nL; ++i){
        for(let k=0; k<nT; ++k){
            maxL[i] = Math.max(maxL[i], grid[i][k]);
            maxT[k] = Math.max(maxT[k], grid[i][k]);
        }
    }
    let count = 0;
    for(let i=0; i<nL; ++i){
        for(let k=0; k<nT; ++k){
            count = count + Math.min(maxL[i], maxT[k]) - grid[i][k];
        }
    }
    return count;
};

思路

题目的大概意思是对于二维数组中的每个点,将其增加到原本二维数组该值所在的行最大值与列
最大值之间较小的那一个值,由此得到一个增量,最终的结果是将所有的增量相加即可得到最后的结果,而我们首先遍历一遍二维数组,取得所有行与列的最大值并分别存储,再进行一次遍历取得该值在取得两个最大值中较小值的增量相加并返回即可。首先分别定义行数即从左向右的水平方向数量nL与列数即从上到下的数值方向数量nT,在这里题目中给出grid.length = grid[0].length所以直接使用相同值即可,之后分别根据两个长度初始化值全是0的数组,进行第一次循环grid,将各行中最大值与各列中最大值分别保存在maxLmaxT数组中,之后定义总数count初始化为0,进行第二次循环grid,循环中取该值以及该值的行最大值与列最大值中较小的一个作差,并与count相加,在循环结束后返回count即可。

每日一题

https://github.com/WindrunnerMax/EveryDay

参考

https://leetcode-cn.com/problems/max-increase-to-keep-city-skyline/
原文地址:https://www.cnblogs.com/WindrunnerMax/p/14074702.html