131. The Skyline Problem 矩形并问题

描述

水平面上有 N 座大楼,每座大楼都是矩阵的形状,可以用一个三元组表示 (start, end, height),分别代表其在x轴上的起点,终点和高度。大楼之间从远处看可能会重叠,求出 N 座大楼的外轮廓线。

外轮廓线的表示方法为若干三元组,每个三元组包含三个数字 (start, end, height),代表这段轮廓的起始位置,终止位置和高度。

请注意合并同样高度的相邻轮廓,不同的轮廓线在x轴上不能有重叠。

您在真实的面试中是否遇到过这个题?  是

样例

给出三座大楼:

[
  [1, 3, 3],
  [2, 4, 4],
  [5, 6, 1]
]

外轮廓线为:

[
  [1, 2, 3],
  [2, 4, 4],
  [5, 6, 1]
]

一开始没想明白怎么做,看题目像是矩形并集问题,一直在往线段树之类的方面想。后来看了别人的解题报告,发现是自己想偏了。

具体做法是把所有的线段的两个端点分别当成两个点保存起来,然后按x轴排序,保存时需要保存这个点是线段的起点还是终点。

接下来扫描所有点:若是起点,则往一个multiset当中插入一个当前线段的高,如果这个插入的高是目前set中的最大值,记录下left,如果不是最大值,不记录left,但是要往multiset插入当前的高。如果是终点,则在multiset中移除当前线段的高。此时观察被移除的高是否是multiset的最大值,如果不是最大值,证明当前的节点是被更高的楼覆盖了,如果是最大值,则说明当前的x就是right,保存left,right,height,存入答案数组。

大体的思路如上

然后就是这个题的各种细节很多,比如有重复点问题、当multiset为空时的处理。

重复点问题我的处理方案是非常小心的设计了排序函数,multiset为空时,有做特殊处理

具体看看代码吧,写的很冗长。

另:我看过别人的解题报告,有很多虽然思路一样但是质量很高很简洁的代码,值得学习

struct node{
    int x;
    int height;
    bool is_begin;
};

bool node_cmp(node a,node b)
{
    if(a.x==b.x)
    {
        if(a.is_begin&&b.is_begin)
            return a.height>b.height;
        else if(!a.is_begin&&!b.is_begin)
            return a.height<b.height;
		else
			return a.is_begin;
    }
    else
        return a.x<b.x;
}

class Solution {
public:
    vector<vector<int>> buildingOutline(vector<vector<int>> &buildings)
    {
        int i;
        vector<vector<int>>::const_iterator iter;
        vector<node> node_list;
        for(iter=buildings.cbegin();iter!=buildings.cend();++iter)
        {
            node temp;
            temp.x=(*iter)[0];
            temp.height=(*iter)[2];
            temp.is_begin=true;
            node_list.push_back(temp);
            temp.x=(*iter)[1];
            temp.height=(*iter)[2];
            temp.is_begin=false;
            node_list.push_back(temp);
        }
        sort(node_list.begin(),node_list.end(),node_cmp);
        multiset<int,greater<int>> height_set;
        vector<vector<int>> result;
        int left,right;
        for(i=0;i<node_list.size();++i)
        {
            node temp_node=node_list[i];
            if(height_set.empty())
            {
                left=temp_node.x;
                height_set.insert(temp_node.height);
            }
            else
            {
                if(temp_node.is_begin)
                {
                    int origen_max=(*height_set.begin());
                    if(temp_node.height>origen_max)
                    {
						height_set.insert(temp_node.height);
                        right=temp_node.x;
                        vector<int>temp;
                        temp.push_back(left);
                        temp.push_back(right);
                        temp.push_back(origen_max);
                        result.push_back(temp);
						left=temp_node.x;
                    }
					else
					{
						height_set.insert(temp_node.height);
					}
                }
                else
                {
                    int origen_max=(*height_set.begin());
                    multiset<int,less<int>>::iterator delete_iter=height_set.find(temp_node.height);
                    height_set.erase(delete_iter);
					if(height_set.empty())
					{
						vector<int>temp;
						right=temp_node.x;
                        temp.push_back(left);
                        temp.push_back(right);
                        temp.push_back(origen_max);
                        result.push_back(temp);
					}
                    else if(origen_max!=(*height_set.begin()))
                    {
						vector<int>temp;
						right=temp_node.x;
                        temp.push_back(left);
                        temp.push_back(right);
                        temp.push_back(origen_max);
                        result.push_back(temp);
                        left=temp_node.x;
                    }
                }
            }
        }
        return result;
    }
};

 

在IT领域,尤其是地理信息系统(GIS)中,坐标转换是一项关键技术。本文将深入探讨百度坐标系、火星坐标系和WGS84坐标系之间的相互转换,并介绍如何使用相关工具进行批量转换。 首先,我们需要了解这三种坐标系的基本概念。WGS84坐标系,即“World Geodetic System 1984”,是一种全球通用的地球坐标系统,广泛应用于GPS定位和地图服务。它以地球椭球模型为基础,以地球质心为原点,是国际航空和航海的主要参考坐标系。百度坐标系(BD-09)是百度地图使用的坐标系。为了保护隐私和安全,百度对WGS84坐标进行了偏移处理,导致其与WGS84坐标存在差异。火星坐标系(GCJ-02)是中国国家测绘局采用的坐标系,同样对WGS84坐标进行了加密处理,以防止未经授权的精确位置获取。 坐标转换的目的是确保不同坐标系下的地理位置数据能够准确对应。在GIS应用中,通常通过特定的算法实现转换,如双线性内插法或四参数转换法。一些“坐标转换小工具”可以批量转换百度坐标、火星坐标与WGS84坐标。这些工具可能包含样本文件(如org_xy_格式参考.csv),用于提供原始坐标数据,其中包含需要转换的经纬度信息。此外,工具通常会附带使用指南(如重要说明用前必读.txt和readme.txt),说明输入数据格式、转换步骤及可能的精度问题等。x86和x64目录则可能包含适用于32位和64位操作系统的软件或库文件。 在使用这些工具时,用户需要注意以下几点:确保输入的坐标数据准确无误,包括经纬度顺序和浮点数精度;按照工具要求正确组织数据,遵循读写规则;注意转换精度,不同的转换方法可能会产生微小误差;在批量转换时,检查每个坐标是否成功转换,避免个别错误数据影响整体结果。 坐标转换是GIS领域的基础操作,对于地图服务、导航系统和地理数据分析等至关重要。理解不同坐标系的特点和转换方法,有助于我们更好地处
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值