Max Increase to Keep City Skyline

Max Increase to Keep City Skyline

In a 2 dimensional array grid, each value grid[i][j] represents the height of a building located there. We are allowed to increase the height of any number of buildings, by any amount (the amounts can be different for different buildings). Height 0 is considered to be a building as well.

At the end, the “skyline” when viewed from all four directions of the grid, i.e. top, bottom, left, and right, must be the same as the skyline of the original grid. A city’s skyline is the outer contour of the rectangles formed by all the buildings when viewed from a distance. See the following example.

What is the maximum total sum that the height of the buildings can be increased?

Example:
Input: grid = [[3,0,8,4],[2,4,5,7],[9,2,6,3],[0,3,1,0]]
Output: 35
Explanation: 
The grid is:
[ [3, 0, 8, 4], 
  [2, 4, 5, 7],
  [9, 2, 6, 3],
  [0, 3, 1, 0] ]

The skyline viewed from top or bottom is: [9, 4, 8, 7]
The skyline viewed from left or right is: [8, 7, 9, 3]

The grid after increasing the height of buildings without affecting skylines is:

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

Notes:

1 < grid.length = grid[0].length <= 50.
All heights grid[i][j] are in the range [0, 100].
All buildings in grid[i][j] occupy the entire grid cell: that is, they are a 1 x 1 x grid[i][j] rectangular prism.

问题剖析

在一个二维素组中,首先我们需要从上到下获取每行里边的最大值,形成一个列表;然后从左到右获取每列中的最大值,形成另外一个列表。 这里需要解决一个会产生冲突的问题,如下所示:

[ [3, 0, 8, 4], 
  [2, 4, 5, 7],
  [9, 2, 6, 3],
  [0, 3, 1, 0] ]

上面这个二维数组,第二列的元素是[0,4,2,3], 第二列的最大元素是4,那么按理说其他不足4的都应该补齐成4.但是还有另外一个限定条件,那就是如果第二列的元素所在行的最大元素必须大于4才可以,但是最后一行的最大元素是3,就不满足条件,此时这列的这个元素只能填充到MIN(当前行的最大值,当前列的最大值),选择两个值中较小的一个座位补充后的目标值。

代码实现如下:

func maxIncreaseKeepingSkyline(grid [][]int) int {
    
    rowsLen := len(grid)
    colsLen := len(grid[0])
    
    maxRows := make([]int, rowsLen)
    maxCols := make([]int, colsLen)
    
    for i := 0; i < rowsLen; i++ {
        for j := 0; j < colsLen; j++ {
            
            gridVal := grid[i][j]
            
            if gridVal > maxRows[i] {
                maxRows[i] = gridVal
            }
            
            if gridVal > maxCols[j] {
                maxCols[j] = gridVal
            }
        }
    }
    
    increaseNum := 0
    for i := 0; i < rowsLen; i++ {
        for j := 0; j < colsLen; j++ {
            maxHeight := maxCols[j]
            if maxRows[i] < maxHeight {
                maxHeight = maxRows[i]
            }
            increaseNum += maxHeight - grid[i][j]
        }
    }
    
    return increaseNum
}