1. 程式人生 > >[LeetCode] 807. Max Increase to Keep City Skyline

[LeetCode] 807. Max Increase to Keep City Skyline

即將 diff 替換 sta 關閉 any same oca 圖片

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.

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] ]

解:
在不破壞天際線的前提下,建築物的高度有兩個限制

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

技術分享圖片

附上代碼

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 調用

Reference

  1. https://www.jianshu.com/p/fa8ad995d300

[LeetCode] 807. Max Increase to Keep City Skyline