城市天际线问题 | 第一部分

给定二维城市中的 n 栋矩形建筑,计算出这些建筑的天际线,并消除被遮挡的线条。我们的主要任务是从侧面观察这些建筑,并移除所有不可见的部分。所有建筑共用同一个底部,且每栋建筑都由一个三元组 来表示:

  • ‘left‘:建筑左侧(或墙)的 x 坐标。
  • ‘right‘:建筑右侧的 x 坐标。
  • ‘ht‘:建筑的高度。

天际线是一系列矩形条的集合。每一个矩形条表示为一对 ,其中 left 是该条左侧的 x 坐标,ht 是该条的高度。

示例:

> 输入: build[][] = [[1, 5, 11], [2, 7, 6], [3, 9, 13], [12, 16, 7], [14, 25, 3], [19, 22, 18], [23, 29, 13], [24, 28, 4]]

> 输出: [[1, 11], [3, 13], [9, 0], [12, 7], [16, 3], [19, 18], [22, 3], [23, 13], [29, 0]]

> 解释: 天际线是基于关键点(图中用“绿色”点表示)形成的,这些关键点消除了被遮挡的墙体。请注意,第二栋建筑 (2, 7, 6) 没有端点被考虑在内,因为它被完全重叠了。此外,y 坐标发生变化的点也被考虑在内。(注意,第三栋建筑 (3, 9, 13) 的右上角点没有被考虑,因为它具有相同的 y 坐标。)

>

> !sl1城市天际线问题

> 输入build[ ][ ] = [[1, 5, 11]]

> 输出[[1, 11], [5, 0]]

解法的通用背景

让我们通过第一个示例 [[1, 5, 11], [2, 7, 6], [3, 9, 13], [12, 16, 7], [14, 25, 3], [19, 22, 18], [23, 29, 13], [24, 28, 4]] 来更好地理解这个问题。

有一点很明显,我们要从左到右构建天际线。现在我们知道点 [1, 11] 肯定会出现在输出中,因为它是最左边的点。

如果我们看第一栋建筑的右点 INLINECODEe4a157a2,会发现这个点不能被计入,因为有一栋更高的建筑(我们输入数组中的第三栋建筑 INLINECODE8f7de139)。所以我们忽略这个右点。

现在我们来看第二栋建筑,它的左边和右边都被覆盖了。左边被第一栋建筑覆盖,右边被第三栋建筑覆盖,因为它的高度比它两边的邻居都小。所以我们完全忽略第二栋建筑。

我们用同样的方式处理所有剩余的建筑。

朴素扫描线算法 – O(n^2) 时间复杂度和 O(n) 空间复杂度

  • 将所有建筑的所有角点 x 坐标放入一个数组,比如 points[]。因为每栋建筑都有左右两个坐标,所以这个数组中主要会有 2n 个点。
  • points[] 进行排序,以模拟从左到右的扫描线。
  • 现在遍历排序后的 points[],对于每一个 x 点,检查哪栋建筑在该点具有最大高度,并且如果最大高度与之前添加到天际线的高度不同,则将此最大高度添加到天际线中。

C++

#include 
#include 
#include 
using namespace std;

vector<pair> getSkyline(vector<vector>& build) {
    vector points;

    // Collect all left and right x-coordinates
    // of buildings
    for (auto& b : build) {
        points.push_back(b[0]);
        points.push_back(b[1]);
    }

    // Sort all critical points
    sort(points.begin(), points.end());

    vector<pair> res;
    int prev = 0;

    // Traverse through each point to
    // determine skyline height
    for (int x : points) {
        int maxH = 0;

        // Check which buildings cover the 
        // current x and get the max height
        for (auto& b : build) {
            int l = b[0], r = b[1], h = b[2];
            if (l <= x && x < r) {
                maxH = max(maxH, h);
            }
        }

        // Add to result if height has changed
        if (res.empty() || maxH != prev) {
            res.push_back({x, maxH});
            prev = maxH;
        }
    }

    return res;
}

int main() {
    vector<vector> build = {
        {2, 9, 10},
        {3, 6, 15},
        {5, 12, 12}
    };

    vector<pair> skyline = getSkyline(build);

    for (auto& p : skyline) {
        cout << "(" << p.first << ", " << p.second << ") ";
    }

    cout << endl;
    return 0;
}

`

Java

import java.util.*;

class Solution {
    public List getSkyline(int[][] build) {
        List points = new ArrayList();

        // Collect all left and right x-coordinates
        // of buildings
        for (int[] b : build) {
            points.add(b[0]);
            points.add(b[1]);
        }

        // Sort all critical points
        Collections.sort(points);

        List res = new ArrayList();
        int prev = 0;

        // Traverse through each point to
        // determine skyline height
        for (int x
声明:本站所有文章,如无特殊说明或标注,均为本站原创发布。任何个人或组织,在未征得本站同意时,禁止复制、盗用、采集、发布本站内容到任何网站、书籍等各类媒体平台。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。如需转载,请注明文章出处豆丁博客和来源网址。https://shluqu.cn/39534.html
点赞
0.00 平均评分 (0% 分数) - 0