【LetMeFly】两种方法解决 699.掉落的方块

力扣题目链接:https://leetcode.cn/problems/falling-squares/

在无限长的数轴(即x轴)上,我们根据给定的顺序放置对应的正方形方块。

i个掉落的方块(positions[i] = (left, side_length))是正方形,其中 left 表示该方块最左边的点位置(positions[i][0]),side_length 表示该方块的边长(positions[i][1])。

每个方块的底部边缘平行于数轴(即 x 轴),并且从一个比目前所有的落地方块更高的高度掉落而下。在上一个方块结束掉落,并保持静止后,才开始掉落新方块。

方块的底边具有非常大的粘性,并将保持固定在它们所接触的任何长度表面上(无论是数轴还是其他方块)。邻接掉落的边不会过早地粘合在一起,因为只有底边才具有粘性

返回一个堆叠高度列表ans。每一个堆叠高度ans[i]表示在通过positions[0], positions[1], ..., positions[i]表示的方块掉落结束后,目前所有已经落稳的方块堆叠的最高高度。

示例 1:

输入: [[1, 2], [2, 3], [6, 1]]
输出: [2, 5, 5]
解释:第一个方块 positions[0] = [1, 2] 掉落:
_aa
_aa
-------
方块最大高度为 2 。第二个方块 positions[1] = [2, 3] 掉落:
__aaa
__aaa
__aaa
_aa__
_aa__
--------------
方块最大高度为5。
大的方块保持在较小的方块的顶部,不论它的重心在哪里,因为方块的底部边缘有非常大的粘性。第三个方块 positions[1] = [6, 1] 掉落:
__aaa
__aaa
__aaa
_aa
_aa___a
--------------
方块最大高度为5。因此,我们返回结果[2, 5, 5]。

示例 2:

输入: [[100, 100], [200, 100]]
输出: [100, 100]
解释: 相邻的方块不会过早地卡住,只有它们的底部边缘才能粘在表面上。

提示:

  • 1≤positions.length≤10001\leq positions.length\leq 10001≤positions.length≤1000
  • 1≤positions[i][0]≤1081\leq positions[i][0]\leq10^81≤positions[i][0]≤108
  • 1≤positions[i][1]≤1061\leq positions[i][1]\leq10^61≤positions[i][1]≤106

思路

主要思路就是判断每个方块下落地的最大已有高度并更新记录之。

方法一:暴力枚举

这题中方块数量的上限是100010001000,因此可以在O(n2)O(n^2)O(n2)的复杂度内通过该题。

我们可以自定义一种数据结构Line

struct Line {int l, r;  // max{l} = max{positions[i][0]} ≤ 1e8 < INT_MAX;max{l} = max{l} + max{length} = max{positions[i][0]} + max{positions[i][1]} ≤ 1.01e8 < INT_MAX int height;  // max{height} ≤ sum{length} ≤ max{positions.length} * max{positions[i][1]} ≤ 1e9 < INT_MAX
};

代表 [l, r]的最大高度都是height

这样我们就可以依次模拟每个方块的下落,对于每个方块,遍历所有的Line,如果这个Line和这个方块有交集,就更新这个方块的最大高度。

  • 时间复杂度O(n2)O(n^2)O(n2),其中nnn是方块的个数
  • 空间复杂度O(1)O(1)O(1),返回值不计入空间复杂度

AC代码

C++

class Solution {public:vector<int> fallingSquares(vector<vector<int>>& positions) {vector<Line> lines;vector<int> ans;  // 答案int Max = 0;  // 最大高度for (auto& thisSquare : positions) {int l = thisSquare[0], r = thisSquare[0] + thisSquare[1] - 1;  // 这个方块的水平投影的范围是[l, r]int thisMaxHeight = thisSquare[1];  // 这个方块的最大高度for (Line& thisLine : lines) {  // 遍历每一条Lineif (!(thisLine.r < l || thisLine.l > r)) {  // 如果这条Line和方块水平投影有交集thisMaxHeight = max(thisMaxHeight, thisLine.height + thisSquare[1]);  // 更新这条线的最大高度}}lines.push_back(Line(l, r, thisMaxHeight));  // 更新插入这条Line(这里不用erase之前被覆盖掉的Line,因为方块只会越摞越高)Max = max(Max, thisMaxHeight);ans.push_back(Max);}return ans;}
};

方法二:有序集合

如果n的范围再增大一些呢?有没有一种时间复杂度为O(nlog⁡n)O(n\log n)O(nlogn)的方法呢

我们来分析以下时间主要消耗在哪里。主要就是对Line的遍历。每下落一个方块都要对所有的Line进行一次遍历。

那么,如果我们维护一个有序的lines的话,是不是就可以了呢?

也就是说,查询已有的重叠的Line的时候,我们可以使用二分法在O(log⁡n)O(\log n)O(logn)的时间复杂度内查找;在插入新Line的时候,我们可以用O(log⁡n)O(\log n)O(logn)的时间复杂度插入到对应位置。同时记得还需要删除被覆盖的Line。

其实,我们可以采用方法一的思想,但是使用一个新的数据结构:map<int, int>。不同编程语言具体实现方式可能不同,这里就以C++为例:

定义一个map<int, int>类型的heightMapheightMap[x1]代表从x1开始,知道遇到下一个x2之前,所有的位置高度都是heightMap[x1]。( [X1, x2) )

在下落一个新的方块时,假设方块范围是[l, r],那么我们要先求得有序集合中[l, r]的最大高度,加上方块边长就是[l, r]的新的高度。

求得新的高度后,删除[l, r]中的原始高度,插入[l, r]的新的高度即可。

  • 时间复杂度O(nlog⁡n)O(n\log n)O(nlogn),其中nnn是方块的个数
  • 空间复杂度O(1n)O(1n)O(1n),返回值不计入空间复杂度

AC代码

C++

class Solution {public:vector<int> fallingSquares(vector<vector<int>>& positions) {vector<Line> lines;vector<int> ans;  // 答案int Max = 0;for (auto& thisSquare : positions) {int l = thisSquare[0], r = thisSquare[0] + thisSquare[1] - 1;  // 这个方块的水平投影的范围是[l, r]int thisMaxHeight = thisSquare[1];  // 这个方块的最大高度for (Line& thisLine : lines) {  // 遍历每一条Lineif (!(thisLine.r < l || thisLine.l > r)) {  // 如果这条Line和方块水平投影有交集thisMaxHeight = max(thisMaxHeight, thisLine.height + thisSquare[1]);  // 更新这条线的最大高度}}lines.push_back(Line(l, r, thisMaxHeight));  // 更新插入这条Line(这里不用erase之前被覆盖掉的Line,因为方块只会越摞越高)Max = max(Max, thisMaxHeight);ans.push_back(Max);}return ans;}
};

同步发文于CSDN,原创不易,转载请附上原文链接哦~
Tisfy:https://letmefly.blog.csdn.net/article/details/124978728

LeetCode 0699.掉落的方块相关推荐

  1. Leetcode 699. 掉落的方块 C++

    Leetcode 699. 掉落的方块 题目 在无限长的数轴(即 x 轴)上,我们根据给定的顺序放置对应的正方形方块. 第 i 个掉落的方块(positions[i] = (left, side_le ...

  2. Java实现 LeetCode 699 掉落的方块(线段树?)

    699. 掉落的方块 在无限长的数轴(即 x 轴)上,我们根据给定的顺序放置对应的正方形方块. 第 i 个掉落的方块(positions[i] = (left, side_length))是正方形,其 ...

  3. leetcode:699. 掉落的方块【segmentTree + lazyTag + 区间修改区间查询经典版子】

    分析 每掉下一个正方形,就要找到落下的区间的最大值 然后再统一更新当前区间的最大值 然后每次返回整个区间的最大值,也就是tree[0] ac code class Solution:def __ini ...

  4. LeetCode 鸡蛋掉落(最清晰的解法)

    你将获得 K 个鸡蛋,并可以使用一栋从 1 到 N 共有 N 层楼的建筑. 每个蛋的功能都是一样的,如果一个蛋碎了,你就不能再把它掉下去. 你知道存在楼层 F ,满足 0 <= F <= ...

  5. leetcode零散题汇总

    零散题 golang力扣leetcode 15.三数之和 golang力扣leetcode 128. 最长连续序列 golang力扣leetcode 1345.跳跃游戏IV golang力扣leetc ...

  6. 【leetcode】鸡蛋掉落问题

    在leetcode刷动态规划问题过程中,鸡蛋掉落问题是比较经典的,特别是笔试面试喜欢出的问题.腾讯,Vivo等大厂都出现过,在这里通过自己学习,以及借鉴大佬的思路,对这道题进行整理. 其它算法问题刷题 ...

  7. C#LeetCode刷题-二叉搜索树

    二叉搜索树篇 # 题名 刷题 通过率 难度 220 存在重复元素 III 19.3% 中等 315 计算右侧小于当前元素的个数 31.9% 困难 327 区间和的个数 29.5% 困难 352 将数据 ...

  8. Leetcode练习题:复杂数据结构

    Leetcode练习题:复杂数据结构 720:词典中最长的单词 问题描述 解题思路 代码实现 反思与收获 1023:驼峰式匹配 问题描述 解题思路 代码实现 反思与收获 问题描述 解题思路 代码实现 ...

  9. Leetcode每日一题总目录(动态更新。。。)

    0. 概要 leecode每日一题(也可能多题)题解跟踪记录及总目录. 常用算法解题思路和技巧及数据结构: 预处理:数组排序(954),哈希表... 双指针法 682,125,905 单向链表 2 双 ...

最新文章

  1. python基础--4 元祖
  2. Android Studio failed to resolve .....
  3. 【theano-windows】学习笔记二——theano中的函数和共享参数
  4. docker jenkins
  5. Android 使用AsyncTask 后监听异步加载完毕的动作
  6. 使用mingw编译log4cpp--问题整理
  7. 以下是一段歌词,请从这段歌词中统计出朋友出现的次数。 这些年一个人,风也过,雨也走,有过泪,有过错, 还记得坚持甚么,真爱过才会懂,会寂寞会回首,终有梦终有你在心中。 朋友一生一起走,那些日子不再
  8. 计算机系统汉字编码分为,计算机中的汉字编码
  9. 苹果在旧设备中修复了两个 iOS 零日漏洞
  10. jquery实现全选
  11. Setting property ‘source‘ to ‘org.eclipse.jst.jee.server
  12. 基于Spark的电影推荐系统(推荐系统~1)
  13. 大学计算机操作题模拟,《大学计算机基础》上模拟试卷操作题
  14. 面试系列——Java工作6年面试拼多多和阿里经历附带面试题
  15. HP C7000刀片服务器学习一
  16. react之间的组件传值
  17. mt6739芯片功能+处理器资料介绍
  18. 基于MQTT应用层协议的物联网家庭温湿度监测系统
  19. 6个你必须用到AJAX的地方与6个不必用到的地方(转载)
  20. MongoDB+集成SpringBoot+索引+并发优化 - 基于《MongoDB进阶与实战:唐卓章》

热门文章

  1. Frontiers in Neuroscience:弥散张量成像(DTI)研究指南
  2. hibernate学习之四——Query和Criteria接口
  3. 漏刻有时数据可视化Echarts组件开发(2):根据温度阈值显示不同颜色的温度报警动画
  4. 转载-杭电老师的思考
  5. 曾因“贿赂”苹果被罚款 10.3 亿美元,高通上诉成功
  6. 离散型随机变量及其分布
  7. 校园跑腿的优势和劣势
  8. 海量文件、超大文件,如何实现高速传输?
  9. “掌上运维” – 下一代网管的思考
  10. 努比亚z11mini 使用 移动物联卡