题目
城市的 天际线 是从远处观看该城市中所有建筑物形成的轮廓的外部轮廓。给你所有建筑物的位置和高度,请返回 由这些建筑物形成的 天际线 。
每个建筑物的几何信息由数组 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