题目

类型:贪心
image.png

解题思路

根据题意,需要确保在调整建筑物高度后,从「水平」和「竖直」两个方向所看到的「行」和「列」的最大高度不变。
因此我们可以先通过O(n * m)的复杂度预处理出 grid 中每行的最大值(使用 r 数组存储),以及每列的最大值(使用 c 数组存储)。
然后在统计答案时,通过判断当前位置 g[i][j]min(r[i],c[j])的大小关系来决定当前位置能够增高多少。
可以证明,当每个位置都取得最大的增大高度(局部最优)时,可使得总的增加高度最大(全局最优)。

代码

  1. class Solution {
  2. public int maxIncreaseKeepingSkyline(int[][] grid) {
  3. int n = grid.length, m = grid[0].length;
  4. int[] r = new int[n], c = new int[m];
  5. for (int i = 0; i < n; i++) {
  6. for (int j = 0; j < m; j++) {
  7. r[i] = Math.max(r[i], grid[i][j]);
  8. c[j] = Math.max(c[j], grid[i][j]);
  9. }
  10. }
  11. int ans = 0;
  12. for (int i = 0; i < n; i++) {
  13. for (int j = 0; j < m; j++) {
  14. ans += Math.min(r[i], c[j]) - grid[i][j];
  15. }
  16. }
  17. return ans;
  18. }
  19. }