# 天际线问题

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

<p>每个建筑物的几何信息由数组 <code>buildings</code> 表示，其中三元组 <code>buildings[i] = [lefti, righti, heighti]</code> 表示：</p>

<ul>
	<li><code>left<sub>i</sub></code> 是第 <code>i</code> 座建筑物左边缘的 <code>x</code> 坐标。</li>
	<li><code>right<sub>i</sub></code> 是第 <code>i</code> 座建筑物右边缘的 <code>x</code> 坐标。</li>
	<li><code>height<sub>i</sub></code> 是第 <code>i</code> 座建筑物的高度。</li>
</ul>

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

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



<p><strong>示例 1：</strong></p>
<img alt="" src="https://assets.leetcode.com/uploads/2020/12/01/merged.jpg" style="width: 800px; height: 331px;" />
<pre>
<strong>输入：</strong>buildings = [[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]]

<strong>输出：</strong>[[2,10],[3,15],[7,12],[12,0],[15,10],[20,8],[24,0]]

<strong>解释：</strong>

图 A<strong> </strong>显示输入的所有建筑物的位置和高度，

图 B 显示由这些建筑物形成的天际线。图 B 中的红点表示输出列表中的关键点。</pre>

<p><strong>示例 2：</strong></p>

<pre>
<strong>输入：</strong>buildings = [[0,2,3],[2,5,3]]

<strong>输出：</strong>[[0,3],[5,0]]
</pre>



<p><strong>提示：</strong></p>

<ul>
	<li><code>1 <= buildings.length <= 10<sup>4</sup></code></li>
	<li><code>0 <= left<sub>i</sub> < right<sub>i</sub> <= 2<sup>31</sup> - 1</code></li>
	<li><code>1 <= height<sub>i</sub> <= 2<sup>31</sup> - 1</code></li>
	<li><code>buildings</code> 按 <code>left<sub>i</sub></code> 非递减排序</li>
</ul>

<p>以下<span style="color:red">错误</span>的选项是？</p>


## 答案

```c
class Solution
{
public:
    vector<vector<int>> getSkyline(vector<vector<int>> &buildings)
    {
        if (buildings.empty())
            return {};
        multiset<pair<int, int>> st;

        for (auto b : buildings)
        {
            st.insert(make_pair(b[0], -b[2]));
            st.insert(make_pair(b[1], b[2]));
        }

        vector<vector<int>> ret;
        multiset<int> height = {0};
        int m = 0;

        for (auto s : st)
        {
            if (s.second < 0)
                height.insert(-s.second);
            else
                height.erase(height.find(s.second));
            if (m != *height.rbegin())
                ret.push_back({s.first, *height.rbegin()});
        }

        return ret;
    }
};
```
## 选项


### A

```c
class Solution
{
public:
    vector<vector<int>> getSkyline(vector<vector<int>> &buildings)
    {
        vector<pair<int, int>> h;
        multiset<int> m;
        vector<vector<int>> res;

        for (const auto &b : buildings)
        {
            h.push_back({b[0], -b[2]});
            h.push_back({b[1], b[2]});
        }

        sort(h.begin(), h.end());

        int prev = 0, cur = 0;
        m.insert(0);

        for (auto i : h)
        {
            if (i.second < 0)
                m.insert(-i.second);
            else
                m.erase(m.find(i.second));
            cur = *m.rbegin();
            if (cur != prev)
            {
                res.push_back({i.first, cur});
                prev = cur;
            }
        }
        return res;
    }
};
```

### B

```c
class Solution
{
public:
    vector<vector<int>> getSkyline(vector<vector<int>> &buildings)
    {
        multiset<pair<int, int>> all;
        vector<vector<int>> res;

        for (auto &e : buildings)
        {
            all.insert(make_pair(e[0], -e[2]));
            all.insert(make_pair(e[1], e[2]));
        }

        multiset<int> heights({0});
        vector<int> last = {0, 0};
        for (auto &e : all)
        {

            e.second < 0 ? heights.insert(-e.second) : heights.erase(heights.find(e.second));
            auto max_height = *heights.rbegin();

            if (last[1] != max_height)
            {

                last[0] = e.first;
                last[1] = max_height;
                res.push_back(last);
            }
        }
        return res;
    }
};
```

### C

```c
class Solution
{
public:
    vector<vector<int>> getSkyline(vector<vector<int>> &buildings)
    {
        multiset<pair<int, int>> all;
        vector<vector<int>> res;

        for (auto &e : buildings)
        {
            all.insert(make_pair(e[0], -e[2]));
            all.insert(make_pair(e[1], e[2]));
        }

        multiset<int> heights;
        heights.insert(0);
        vector<int> last;
        last.push_back(0);
        last.push_back(0);

        for (auto &p : all)
        {
            if (p.second < 0)
                heights.insert(-p.second);
            else
                heights.erase(heights.find(p.second));

            auto maxHeight = *heights.rbegin();

            if (last[1] != maxHeight)
            {
                last[0] = p.first;
                last[1] = maxHeight;

                res.push_back(last);
            }
        }

        return res;
    }
};
```
