【LeetCode】699. 掉落的方块

699. 掉落的方块


原题链接: 699. 掉落的方块

题目大意

在二维平面上的 x 轴上,放置着一些方块。
给你一个二维整数数组 positions ,其中 positions[i] = [lefti, sideLengthi] 表示:第i个方块边长为sideLengthi,其左侧边与 x 轴上坐标点 lefti 对齐。
每个方块都从一个比目前所有的落地方块更高的高度掉落而下。方块沿 y 轴负方向下落,直到着陆到 另一个正方形的顶边 或者是 x 轴上 。一个方块仅仅是擦过另一个方块的左侧边或右侧边不算着陆。一旦着陆,它就会固定在原地,无法移动。
在每个方块掉落后,你必须记录目前所有已经落稳的 方块堆叠的最高高度 。
返回一个整数数组 ans ,其中 ans[i] 表示在第 i 块方块掉落后堆叠的最高高度。
示例:
在这里插入图片描述
数据范围:

1 <= positions.length <= 1000
1 <= lefti <= 10^8
1 <= sideLengthi <= 10^6

思路

  • 虽然从实际的区间来看数据范围达到 1 0 8 10^8 108,但方块数量的数据范围<=1000,则相当于对区间做了离散化,只需要遍历positions数组。可采用 O ( n 2 ) O(n^2) O(n2)的暴力解法。线段树解法后面更新。
  • 遍历positions数组,heights数组用来记录当前方块落下后,该区间的最大高度。
    通过positions数组可得到当前方块所占区间的左、右端点,从而可遍历与当前区间有交集的先前区间的最大高度heights[0~i-1],来更新当前区间的最大高度。
    例如方块2落下后,与先前的方块1有交集,则
    heights[1] = max(heights[1],
    heights[0] + position[1][1])=5.
    最终得到heights数组。
  • 题目求的是第 i 块方块掉落后,总体方块堆叠的最高高度,则对heights数组原地操作,对第i项,计算heights数组前i项中的最大值即可。

代码

class Solution {
public:
    vector<int> fallingSquares(vector<vector<int>>& positions) {
        const int N = positions.size();
        vector<int> heights(N); // 当前方块落下后,该区间的最高高度
        int max_h = 0;
        for(int i = 0; i < N; i ++ ){
            int l = positions[i][0], r = l + positions[i][1] - 1;
            heights[i] = positions[i][1]; // 初始化为当前方块的边长

            for(int j = 0; j < i; j ++ ){ // 遍历先前方块对应区间
                int l1 = positions[j][0], r1 = l1 + positions[j][1] - 1;
                // 区间有交集则尝试更新当前最大高度
                if(l <= r1 && r >= l1){ 
                    heights[i] = max(heights[i], heights[j] + positions[i][1]);
                }
            }
        }
		// 第 i 块方块掉落后,总体方块堆叠的最高高度
        for(int i = 1; i < N; i ++ ){
            heights[i] = max(heights[i - 1], heights[i]);
        }

        return heights;
    }
};

复杂度

时间复杂度: O ( n 2 ) O(n^2) O(n2)
空间复杂度: O ( 1 ) O(1) O(1),答案数组不算额外空间

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值