> For the complete documentation index, see [llms.txt](https://zhongwen.gitbook.io/leetcode-report/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://zhongwen.gitbook.io/leetcode-report/medium/807.-max-increase-to-keep-city-skyline-1.md).

# 807. 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.&#x20;

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.

#### 解题要点：

遍历二维数组，找出从左至右，从上到下的最高建筑一维数组。然后再遍历一次，基于这个一维数组判断出哪些建筑还有上升空间，并加盖到不超过最高建筑，将这个升高的值加入最终返回值中。

1ms：

```java
class Solution {
    public int maxIncreaseKeepingSkyline(int[][] grid) {
        int res = 0;
        int[] topdown = new int[grid.length];
        int[] leftright = new int[grid.length];

        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid.length; j++){
                leftright[i] = grid[i][j] > leftright[i] ? grid[i][j] : leftright[i];
                topdown[i] = grid[j][i] > topdown[i] ? grid[j][i] : topdown[i];
            }
        }
        
        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid.length; j++){
                res += Math.min(leftright[i], topdown[j]) - grid[i][j];
            }
        }
        
        return res;
    }
}
```

2ms：

```java
class Solution {
    public int maxIncreaseKeepingSkyline(int[][] grid) {
        int res = 0;
        int[] topdown = new int[grid.length];
        int[] leftright = new int[grid.length];

        for(int i = 0; i < grid.length; i++){
            for(int j = 0; j < grid.length; j++){
                leftright[i] = grid[i][j] > leftright[i] ? grid[i][j] : leftright[i];
                topdown[i] = grid[j][i] > topdown[i] ? grid[j][i] : topdown[i];
            }
        }
        
        for(int w = 0; w < grid.length; w++){
            for(int e = 0; e < grid.length; e++){
                while(grid[w][e] < leftright[w] && grid[w][e] < topdown[e]){
                    grid[w][e]++;
                    res++;
                }
            }
        }
        
        return res;
    }
}
```
