[LeetCode] 807. Max Increase to Keep City Skyline
Description
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] ]
Analyse
在不破坏天际线的前提下,建筑物的高度有两个限制
1.from top or bottom
2.from left or right
要同时满足这两个限制,取最小值即可
先算出一个矩阵的横向最大值和纵向最大值,即天际线
将矩阵中每个元素替换为对应的横向和纵向最大值中的最小值就得到了gridNew
, 作个减法,再把sum加起来就搞定了
horizontal为图中的[9 4 8 7]
vertical为图中的[8 7 9 3]
即将 grid[i][j]
替换为 min(horizontal[j], vertical[i])
图中的红色数字即为gridNew
Code
static int x=[](){
std::ios::sync_with_stdio(false);
cin.tie(NULL);
return 0;
}();
class Solution {
public:
int maxIncreaseKeepingSkyline(vector<vector<int>>& grid) {
vector<int> horizontal;
vector<int> vertical;
for (int i = 0; i < grid.size(); i++)
{
int vertical_max = 0;
int horizontal_max = 0;
for (int j = 0; j < grid.at(i).size(); j++)
{
if (grid.at(i).at(j) > vertical_max)
{
vertical_max = grid.at(i).at(j);
}
if (grid.at(j).at(i) > horizontal_max)
{
horizontal_max = grid.at(j).at(i);
}
}
vertical.push_back(vertical_max);
horizontal.push_back(horizontal_max);
}
int sum = 0;
for (int i = 0; i < grid.size(); i++)
{
for (int j = 0; j < grid.at(i).size(); j++)
{
int max_i_j = (vertical.at(i) < horizontal.at(j)) ? vertical.at(i) : horizontal.at(j);
sum += (max_i_j - grid.at(i).at(j));
grid.at(i).at(j) = max_i_j;
}
}
return sum;
}
};
下面这段代码是leetcode里运行时间为0ms的代码里的,可以减少leetcode里代码的运行时间
static int x=[](){
std::ios::sync_with_stdio(false);
cin.tie(NULL);
return 0;
}();
用 sync_with_stdio 接口,关闭 std::cin 和 std::cout 与 scanf 和 printf 的同步,减少了相当的 IO 开销
用 cin.tie 接口,完成了 cin 和 cout 的解耦,减少了大量 flush 调用