前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
工具
TVP
发布
社区首页 >专栏 >LeetCode 218. The Skyline Problem(线段树+离散化)

LeetCode 218. The Skyline Problem(线段树+离散化)

作者头像
ShenduCC
发布2020-02-19 16:38:09
8700
发布2020-02-19 16:38:09
举报
文章被收录于专栏:算法修养算法修养

题意:就是有一些矩形,然后让你输出一些点,这些点连成的线是这些矩形的外围。叫做城市天际线。具体的看题目就好了。

题解:首先,设立一个区间,用数组表示。每遇到一个矩形,我们就把这个矩形的底部的宽所占的区间的值全部都设成这个矩形的高。在覆盖区间的时候,如果发现这个区间已经被覆盖过,如果当前值比原有值低,就不覆盖了,比原有值高采取覆盖。一开始的区间的长度当然是0,相当于这个城市都是平地。当我们把所有矩形都覆盖之后,把区间的长度当做宽,当做高,就是上面图片中的第二张。然后那些点,怎么确定呢?其实就是从区间的最左边开始,遇到第一个值发生变化的那个点,是我们需要的,然后从这个点再向右找,找到区间值又发生变化的下一个点。以此循环,直到发现某个点向右的值都没有变化了,就停止了。

那上面一系列操作,最合适的数据结构就是线段树了,可以满足的我们的需求。覆盖点,以及找到某个点开始,第一个值发生变化的点。

但是题目的数据范围是0-INTMAX,直接建立线段树会炸的,所以我们必须要离散化!

代码语言:javascript
复制
typedef long long int _int;
class Solution {
public:
    int num[500005];
    int height;
    map<_int,int> m;
    vector<vector<int>> getSkyline(vector<vector<int>>& buildings) {

        vector<vector<int>> ans;
        if(buildings.size()==0)
            return ans;

        memset(num,0,sizeof(num));

        vector<_int> a;
        for(int i=0;i<buildings.size();i++)
        {
            a.push_back(buildings[i][0]);
            a.push_back(buildings[i][1]);
            a.push_back((_int)buildings[i][1]+1);
        }

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

        int pos=0;
        vector<_int> b;
        for(int i=0;i<a.size();i++)
        {
            if(m[a[i]]==0)
            {
                m[a[i]] = ++pos;
                b.push_back(a[i]);
            }
        }

        int last;
        for(int i=0;i<buildings.size();i++)
        {
            update(1,1,pos+2,m[buildings[i][0]],m[buildings[i][1]],buildings[i][2]);
        }

        _int start=1;
        height = 0;
        int pre = height;

        while(1)
        {
            pre = height;

            start = query(1,1,pos+2,start,height);

            if(start==-1)
            {
                break;
            }

            vector<int> res;
            if(height < pre)
                res.push_back(b[start-1]-1);
            else
                res.push_back(b[start-1]);

            res.push_back(height);

            ans.push_back(res);
        }
        return ans;


    }

    void pushup(int node)
    {
        if(num[node<<1]==num[node<<1|1])
            num[node]=num[node<<1];
        else
            num[node]=-1;
    }

    void pushdown(int node)
    {
        if(num[node]!=-1)
        {
            num[node<<1]=num[node];
            num[node<<1|1]=num[node];
        }
    }


    void update(int node,_int l,_int r,_int start,_int end,int val)
    {
        if(start<=l&&r<=end)
        {
            if(num[node]!=-1)
            {
                if(num[node]<val)
                    num[node]=val;

                return;
            }

        }
        pushdown(node);

        _int mid = (l+r)>>1;
        if(start<=mid)
            update(node<<1,l,mid,start,end,val);
        if(end >mid)
            update(node<<1|1,mid+1,r,start,end,val);

        pushup(node);
    }

    int query(int node,_int l,_int r,_int start,_int val)
    {
        if(num[node]!=-1)
        {
            if(num[node]==val)
                return -1;
            else
            {
                height = num[node];
                return l;
            }
        }
        pushdown(node);

        _int mid = (l+r)>>1;
        int res;
        if(start<=mid)
        {
            res = query(node<<1,l,mid,start,val);
            if(res!=-1)
                return res;
        }

        res = query(node<<1|1,mid+1,r,start,val);

        pushup(node);

        return res;
    }


};
本文参与 腾讯云自媒体分享计划,分享自作者个人站点/博客。
原始发表:2020-02-15 ,如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体分享计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
0 条评论
热度
最新
推荐阅读
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档