首页 > 其他分享 >天际线问题

天际线问题

时间:2024-08-13 23:26:00浏览次数:12  
标签:天际线 activeHeights 高度 heights 问题 事件 建筑物

题目描述

城市的 天际线 是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度,请返回 由这些建筑物形成的 天际线 。

每个建筑物的几何信息由数组 buildings 表示,其中三元组 buildings[i] = [lefti, righti, heighti] 表示:

  • lefti 是第 i 座建筑物左边缘的 x 坐标。
  • righti 是第 i 座建筑物右边缘的 x 坐标。
  • heighti 是第 i 座建筑物的高度。

你可以假设所有的建筑都是完美的长方形,在高度为 0 的绝对平坦的表面上。

天际线 应该表示为由 “关键点” 组成的列表,格式 [[x1,y1],[x2,y2],...] ,并按 x 坐标 进行 排序 。关键点是水平线段的左端点。列表中最后一个点是最右侧建筑物的终点,y 坐标始终为 0 ,仅用于标记天际线的终点。此外,任何两个相邻建筑物之间的地面都应被视为天际线轮廓的一部分。

注意:输出天际线中不得有连续的相同高度的水平线。例如 [...[2 3], [4 5], [7 5], [11 5], [12 7]...] 是不正确的答案;三条高度为 5 的线应该在最终输出中合并为一个:[...[2 3], [4 5], [12 7], ...]

示例 1:

输入:buildings = [[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]]
输出:[[2,10],[3,15],[7,12],[12,0],[15,10],[20,8],[24,0]]
解释:
图 A 显示输入的所有建筑物的位置和高度,
图 B 显示由这些建筑物形成的天际线。图 B 中的红点表示输出列表中的关键点。

示例 2:

输入:buildings = [[0,2,3],[2,5,3]]
输出:[[0,3],[5,0]]

提示:

  • 1 <= buildings.length <= 104
  • 0 <= lefti < righti <= 231 - 1
  • 1 <= heighti <= 231 - 1
  • buildings 按 lefti 非递减排序

程序结构解析

class Solution {
public:
    vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {
        vector<pair<int, int>> heights;
        for (const auto& b : buildings) {
            heights.emplace_back(b[0], -b[2]); // negative height for start
            heights.emplace_back(b[1], b[2]);  // positive height for end
        }

        // Sort the heights, ensuring that:
        // 1. Lower x has higher priority
        // 2. If equal x, starts come before ends
        // 3. If equal x and both starts, higher height comes first
        // 4. If equal x and both ends, lower height comes first
        sort(heights.begin(), heights.end());
    
        // Resultant skyline
        vector<vector<int>> skyline;
        multiset<int> activeHeights; // Current active heights
        int prevHeight = 0;
        activeHeights.insert(0); // Ground level
        
        for (const auto& h : heights) {
            if (h.second < 0) { // Building starts
                activeHeights.insert(-h.second);
            } else { // Building ends
                activeHeights.erase(activeHeights.find(h.second));
            }

            // Current max height
            int currentHeight = *activeHeights.rbegin();
            if (currentHeight != prevHeight) {
                skyline.push_back({h.first, currentHeight});
                prevHeight = currentHeight;
            }
        }
        
        return skyline;
    }
};
1. 建筑物事件的处理
  • 建筑物的起始和终止点: 每个建筑物由 [lefti, righti, heighti] 表示,程序首先将每个建筑物转换为两个事件点:

    • 起始事件:(lefti, -heighti),使用负高度表示这是建筑物的起点。
    • 终止事件:(righti, heighti),使用正高度表示这是建筑物的终点。
  • 排序事件: 事件通过 sort() 函数排序。排序规则如下:

    • 首先按 x 坐标(即事件的第一个元素)排序。
    • 如果 x 坐标相同,按高度处理顺序排序(起始事件在前,终止事件在后)。
    • 起始事件中,更高的建筑先处理。
    • 终止事件中,较低的建筑先处理。
2. 管理活跃的建筑高度
  • 活跃高度的跟踪: 使用 multiset<int> 来跟踪当前活跃的建筑物高度。multiset 允许多个相同元素的存在并自动保持元素排序,这使得查询当前最大高度变得简单高效。
3. 天际线的构建
  • 迭代处理每个事件: 遍历排序后的事件列表,根据是起始还是终止事件来更新 multiset

    • 如果是起始事件,则将高度加入 multiset
    • 如果是终止事件,则从 multiset 中移除对应高度。
  • 生成天际线关键点: 每处理完一个事件后,检查当前的最大高度(activeHeights 的最后一个元素,即 *activeHeights.rbegin())。如果最大高度发生变化(与前一个高度 prevHeight 不同),则当前 x 坐标和新的最大高度成为一个新的关键点。

标签:天际线,activeHeights,高度,heights,问题,事件,建筑物
From: https://blog.csdn.net/weixin_45092290/article/details/141176419

相关文章

  • 非线性规划的经典例题--选址问题
    本章会介绍如何利用非线性规划解决选址问题,这个问题是文章线性规划在数学建模中的两道例题中第二道投料问题的第二小题,本章为基于这道题的基础上进行介绍,建议读者返回去看一看目录一、问题提出二、问题分析三、模型建立四、代码实现1.输入目标函数2.输入线性约束一、问题提出......
  • 最小栈问题
    设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。实现 MinStack 类:MinStack() 初始化堆栈对象。voidpush(intval) 将元素val推入堆栈。voidpop() 删除堆栈顶部的元素。inttop() 获取堆栈顶部的元素。intgetMin() 获取堆栈中的最小元素......
  • 【实践问题】UART通信问题解决过程
    近期开发了一项通过UART进行读写操作的功能。说起来并不难,但是实际操作起来还是遇到了不少问题,解决问题也费了一番周折。因此记录下来作为积累,也供遇到类似问题的同学参考。问题背景当前的项目需要开发一项功能:BMC通过UART串口与另一设备通信,进行读写操作。听起来并不难,......
  • golang 管道channel相关问题
    一funcmain(){ c1:=make(chanany) <-c1}上面代码运行肯定会报deadlock的死锁错误,但是下面这样,如果有一个协程一直在运行,则不会报错,大致就是因为协程还在运行,所属主协程main不确定是否会往管道c1中写数据,所以就会一直阻塞在这里,上面的代码块或者没有一直执行的协程......
  • 关于渗透测试靶场搭建的问题(小白经验)
    前言可能会有点啰嗦可以跳过我唠叨的环节,在我学习网络安全的过程中我遇到的问题总是多到离谱可以说比一般人多所以我比较的有点自信做这篇文章总结,当然文章末尾有整合资源懒人就直接拿吧,如果有不对的地方请毫不保留的指出谢谢——————————————————————......
  • inscode的会员计划的python环境问题【版本3.9.16】无法升级python
    购买了inscode的会员计划后,部署python项目遇到python环境无法升级的问题inscode的会员计划的环境是3.9.16,但是项目用的例子需要3.10以上的版本,最终本人也无法完全解决,虽然手动安装了python3.10,一切都可以实现,但是最后环境自动恢复到3.9版本,导致自己手动配置的全废了,本帖子......
  • Java解决递归造成的堆栈溢出问题
    在Java中,递归造成的堆栈溢出问题通常是因为递归调用的深度过大,导致调用栈空间不足。解决这类问题的一种常见方法是使用非递归的方式重写算法,即使用迭代替代递归。1.方法一:非递归的方式重写算法(迭代替代递归)下面通过一个典型的递归例子——计算斐波那契数列的第n项,来演示如何用迭......
  • 通过这五个问题,带你深入了解中国式报表
    一、什么是中国式报表?中国式报表,顾名思义具有中国特色的报表,通常指的是中国企业/机构在财务和业务报告方面的特有风格和规范。 二、中国式报表有什么特点?一句话就可以概括中国式报表:结构复杂、数据量大的一种报表。  ·格式复杂:为了能够展示更为详尽的数据分类和汇总信......
  • unity2022.3.9+Pico更换渲染管线后打包,人物材质不可显示问题
    为了解决字体和场景闪烁问题吗,更换渲染管线旧项目管线是URP 新的项目管线是内置管线buildin()  内置管线需要设置两个地方,可以解决人物材质不显示问题1.PICO-StereoRenderingMode选择 MultiPass模式 2,Player-OtherSetting-AutoGraphicsAPI勾选(注:项目中有......
  • windows系统配置nginx环境运行pbootcms访问首页直接404的问题
    安装pbootcms后访问后台/admin.php可以,但是直接访问首页就404。运行环境运行环境采用的是:windows+nginx+php的环境详细经过客户说伪静态规则一直无法生效,看了一下,代码放到服务器除了后台/admin.php可以访问到,其他页面都是404错误,一直各种尝试导入伪静态,但是所有页面依然是404。......