C++算法:城市天际线问题

简介: C++算法:城市天际线问题

题目

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

每个建筑物的几何信息由数组 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 非递减排序

2023年4月版

class Solution {
public:
vector<vector> getSkyline(vector<vector>& buildings) {
m_c = buildings.size();
vector vBound;
for (const auto& b : buildings)
{
vBound.emplace_back(b[0]);
vBound.emplace_back(b[1]);
}
std::sort(vBound.begin(), vBound.end());
std::priority_queue<std::pair<int, int>, vector<std::pair<int, int>>, NCmp::CLessPair<int,int> > que;
vector<vector> vRet;
int iBuildIndex = 0;
for (const auto& b : vBound)
{
//如果建筑的左边界 小于等于b 加到优先队列
while ((iBuildIndex < m_c) && (buildings[iBuildIndex][0] <= b))
{
que.emplace(buildings[iBuildIndex][2], buildings[iBuildIndex][1]);
iBuildIndex++;
}
//如果建筑的右边界小于等于b,从优先队列删除。因为只取height的值,所以在取值得删除
while (que.size() && (que.top().second <= b))
{
que.pop();
}
int y = que.empty() ? 0 : que.top().first;
if (vRet.empty() || (y != vRet.back()[1]))
{
vRet.push_back(vector{b, y});
}
}
return vRet;
}
int m_c;
};

2023年8月

class Solution {
public:
vector<vector> getSkyline(vector<vector>& buildings) {
m_c = buildings.size();
vector vX;
for (const auto& v : buildings)
{
vX.emplace_back(v[0]);
vX.emplace_back(v[1]);
}
std::sort(vX.begin(), vX.end());
priority_queue<pair<int, int>> maxHeapHeightR;
int inx = 0;
vector<vector> vRet;
for (const auto& x : vX)
{
while ((inx < m_c) && (buildings[inx][0] <= x))
{
maxHeapHeightR.emplace(buildings[inx][2], buildings[inx][1]);
inx++;
}
while (maxHeapHeightR.size() && (maxHeapHeightR.top().second <= x))
{
maxHeapHeightR.pop();
}
const int h = maxHeapHeightR.empty() ? 0 : maxHeapHeightR.top().first;
if (vRet.empty() || (vRet.back()[1] != h))
{
vRet.emplace_back(vector{x, h});
}
}
return vRet;
}
int m_c;
};

其它

视频课程

如果你觉得复杂,想从简单的算法开始,可以学习我的视频课程。

https://edu.csdn.net/course/detail/38771

我的其它课程

https://edu.csdn.net/lecturer/6176

测试环境

win7 VS2019 C++17

相关下载

算法精讲《闻缺陷则喜算法册》doc版

https://download.csdn.net/download/he_zhidan/88348653


相关文章
|
1月前
|
存储 算法 C++
高精度算法(加、减、乘、除,使用c++实现)
高精度算法(加、减、乘、除,使用c++实现)
468 0
高精度算法(加、减、乘、除,使用c++实现)
|
1月前
|
算法 数据处理 C++
c++ STL划分算法;partition()、partition_copy()、stable_partition()、partition_point()详解
这些算法是C++ STL中处理和组织数据的强大工具,能够高效地实现复杂的数据处理逻辑。理解它们的差异和应用场景,将有助于编写更加高效和清晰的C++代码。
22 0
|
1月前
|
存储 算法 决策智能
【算法】博弈论(C/C++)
【算法】博弈论(C/C++)
|
1月前
|
存储 算法 C++
【算法】哈希映射(C/C++)
【算法】哈希映射(C/C++)
|
1月前
|
机器学习/深度学习 人工智能 算法
【算法】最长公共子序列(C/C++)
【算法】最长公共子序列(C/C++)
|
1月前
|
人工智能 算法 BI
一篇带你速通差分算法(C/C++)
一篇带你速通差分算法(C/C++)
|
1月前
|
人工智能 算法 C++
一篇带你速通前缀和算法(C/C++)
一篇带你速通前缀和算法(C/C++)
|
1月前
|
存储 算法 C++
弗洛伊德(Floyd)算法(C/C++)
弗洛伊德(Floyd)算法(C/C++)
|
1月前
|
存储 算法 程序员
迪杰斯特拉(Dijkstra)算法(C/C++)
迪杰斯特拉(Dijkstra)算法(C/C++)
|
1月前
|
算法 C++
【算法解题思想】动态规划+深度优先搜索(C/C++)
【算法解题思想】动态规划+深度优先搜索(C/C++)