0
点赞
收藏
分享

微信扫一扫

1840. 最高建筑高度 贪心


1840. 最高建筑高度

在一座城市里,你需要建 ​​n​​​ 栋新的建筑。这些新的建筑会从 ​​1​​​ 到 ​​n​​ 编号排成一列。

这座城市对这些新建筑有一些规定:

  • 每栋建筑的高度必须是一个非负整数。
  • 第一栋建筑的高度必须是​​0​​ 。
  • 任意两栋相邻建筑的高度差不能超过​1​​ 。

除此以外,某些建筑还有额外的最高高度限制。这些限制会以二维整数数组 ​​restrictions​​​ 的形式给出,其中 ​​restrictions[i] = [idi, maxHeighti]​​​ ,表示建筑 ​​idi​​ 的高度 不能超过 ​​maxHeighti​​ 。

题目保证每栋建筑在 ​​restrictions​​ 中 至多出现一次 ,同时建筑 ​​1​​ 不会 出现在 ​​restrictions​​ 中。

请你返回 最高 建筑能达到的 最高高度 。


示例 1:

1840. 最高建筑高度 贪心_算法

输入:n = 5, restrictions = [[2,1],[4,1]] 输出:2 解释:上图中的绿色区域为每栋建筑被允许的最高高度。 我们可以使建筑高度分别为 [0,1,2,1,2] ,最高建筑的高度为 2 。

示例 2:

1840. 最高建筑高度 贪心_数组_02

输入:n = 6, restrictions = [] 输出:5 解释:上图中的绿色区域为每栋建筑被允许的最高高度。 我们可以使建筑高度分别为 [0,1,2,3,4,5] ,最高建筑的高度为 5 。

示例 3:

1840. 最高建筑高度 贪心_leetcode_03

输入:n = 10, restrictions = [[5,3],[2,5],[7,4],[10,3]] 输出:5 解释:上图中的绿色区域为每栋建筑被允许的最高高度。 我们可以使建筑高度分别为 [0,1,2,3,3,4,4,5,4,3] ,最高建筑的高度为 5 。


提示:

  • ​2 <= n <= 1e9​
  • ​0 <= restrictions.length <= min(n - 1, 1e5)​
  • ​2 <= idi <= n​
  • ​idi​​ 是唯一的
  • ​0 <= maxHeighti <= 1e9​

做题结果

成功,但是想了很久,哈哈速度上不来,开始的时候弄了个循环去硬算左右高度限定后改变的高度,第二遍写了个循环内部再BFS。后面发现仅仅和两侧有关,那左右两边正反循环一遍就行了啊,^_^。

1. 不包含头元素

2. 尾元素可能有可能没有

3. 限高可能有效可能无效,比如第2个限制100,那这个限制就无效

4. 限高可能受到后续影响。比如第一个为0,第三个限高2,第四个限高0,由于后续第四个元素影响,第三个只能最高到达 1,到不了2

方法:贪心

  1. 按照位置排序
  2. 不含第一栋建筑补第一栋
  3. 如果含有最后一栋建筑不用补,否则补一个最后一栋
  4. 对于编号为 i 的建筑,最高为 i-1,先粗略的写个限定
  5. 由于前后限定的值都对当前元素产生影响,不一定能达到限定值,所以按照左右都改一遍限定值,​​curr=min(pre[1]+(curr[0]-pre[0]),curr[1])​​,保证了从前面可以到达后面的高度,反过来保证了从后面可以到达前面的高度(注意:特别小心最后一个元素的处理,从前往后推导是包含最后一个元素的,从后往前不包含)
  6. 推导两个限定高度之间的最大高度:​​(curr[0]-pre[0]-Math.abs(curr[1]-pre[1]))/2+max(pre[1],curr[1]);​
  • 首先两者的较大值是 max(pre[1],curr[1])
  • 然后需要把较小的一个补到最大值,需要 abs(curr[1]-pre[1]) 的距离
  • 两者水平距离是 curr[0]-pre[0],需要刨除掉补到最大值的距离,就变成​​curr[0]-pre[0]-Math.abs(curr[1]-pre[1])​
  • 最后他们的距离除以2,是中间可以突出来的高度,比如 2,4 两个位置高度都是 3,4-2是2,除以2是1,所以中间可以突出1个单位的高度,2+1 得到 3

class Solution {
public int maxBuilding(int n, int[][] restrictions) {
List<int[]> heights = new ArrayList<>();
heights.add(new int[]{1,0});
int m = restrictions.length;
Arrays.sort(restrictions,(a,b)->a[0]-b[0]);
for(int []restrict:restrictions){
restrict[1] = Math.min(restrict[1],restrict[0]-1);
}
heights.addAll(Arrays.asList(restrictions));

//调好限定高度,有些高度可能是坑
if(heights.get(heights.size()-1)[0]!=n) heights.add(new int[]{n,n-1});

for(int i = 1; i < heights.size(); i++){
int[] pre = heights.get(i-1);
int[] curr = heights.get(i);
int m1 = pre[1]+(curr[0]-pre[0]);
curr[1] = Math.min(m1,curr[1]);
}

for(int i = heights.size()-2; i >0 ; i--){
int[] next = heights.get(i+1);
int[] curr = heights.get(i);
int m1 = next[1]+(next[0]-curr[0]);
curr[1] = Math.min(m1,curr[1]);
}
//(end-start-abs(v[end]-v[start]))/2+max(v[end],v[start])
int ans = 0;
for(int i = 1; i < heights.size(); i++){
int[] pre = heights.get(i-1);
int[] curr = heights.get(i);
int max = (curr[0]-pre[0]-Math.abs(curr[1]-pre[1]))/2+Math.max(pre[1],curr[1]);
ans = Math.max(max,ans);
}
return ans;
}
}

时间复杂度:O(nlogn)
空间复杂度:O(n),可以优化到O(1),直接在原数组基础上修改,判断头尾

举报

相关推荐

0 条评论