大楼轮廓问题

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

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

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

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

样例

给出三座大楼:

[

[1, 3, 3],

[2, 4, 4],

[5, 6, 1]
]

外轮廓线为:

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

     

  2.  
  3. //
    //  main.cpp
    //  AdvancedFour
    //
    //  Created by 吴珝君 on 2019/5/22.
    //  Copyright © 2019年 闲着也是贤者. All rights reserved.
    //
    /*
     水平面上有 N 座大楼,每座大楼都是矩阵的形状,可以用一个三元组表示 (start, end, height),分别代表其在x轴上的起点,终点和高度。大楼之间从远处看可能会重叠,求出 N 座大楼的外轮廓线。
     外轮廓线的表示方法为若干三元组,每个三元组包含三个数字 (start, end, height),代表这段轮廓的起始位置,终止位置和高度。
     [[1, 3, 3], [2, 4, 4], [5, 6, 1]]
     [[1, 2, 3],[2, 4, 4],[5, 6, 1] ]
     */
    #include <iostream>
    #include <vector>
    #include <map>
    #include <algorithm>
    using namespace std;
    
    class Position{
        public:
        Position(bool isup, int x, int hight)
        {
            this->isup = isup;
            this->x = x;
            this->hight = hight;
        }
        bool isup;
        int x;
        int hight;
    };
    
    class Building{
        public:
        Building(int start, int end, int hight)
        {
            this->start = start;
            this->end = end;
            this->hight = hight;
        }
        int start;
        int  end;
        int hight;
    };
    bool comp(Position o1, Position o2)
    {
        if (o1.x != o2.x) {
            return o1.x < o2.x;
        }
        if (o1.isup != o2.isup) {
            if (o1.isup) {
                return true;
            }
            return false;
        }
        
        return false;
    }
    class DealDate
    {
        public:
        vector<vector<int>> getOutline(vector<Building> vb)
        {
            vector<vector<int>> res;
            map<int , int> htmap;
            map<int, int> maxmap;
            vector<Position> v = getPosition(vb);
            sort(v.begin(), v.end(), comp);
            for (int i = 0; i < v.size(); i++) {
                if(v[i].isup)
                {
                    if (htmap.count(v[i].hight) == 0)
                    {
                        htmap[v[i].hight] = 1;
                    }
                    else
                    {
                        htmap[v[i].hight]++;
                    }
                }
                else
                {
                    if(htmap.find(v[i].hight)->second>=1)//遍历
                    {
                        if (htmap.find(v[i].hight)->second == 1)
                        {
                            htmap.erase(v[i].hight);
                        }
                        else
                        {
                            htmap[v[i].hight]--;
                        }//
                    }
                }
                if (htmap.empty()) {
                    
                    maxmap[v[i].x] =0;
                }
                else
                {
                    maxmap[v[i].x] = htmap.rbegin()->first;
                    
                }
                
            }
            int h =0;
            int start = 0;
            map<int, int>::iterator it ;
            for ( it = maxmap.begin(); it != maxmap.end(); it++) {
                int hcur = it->second;
                cout << hcur <<endl;
                
                if (h != hcur)
                {
                    if (h !=0)
                    {
                        vector<int> v;
                        v.push_back(start);
                        v.push_back(it->first);
                        v.push_back(h);
                        res.push_back(v);
                    }
                    start = it->first;
                    h = hcur;
                }
            }
            
            return res;
        }
        
        private:
        vector<Position> getPosition(vector<Building> vb)
        {
            vector<Position> v;
            for (int i = 0; i < vb.size(); i++) {
                v.push_back(Position( true,vb[i].start,vb[i].hight));
                v.push_back(Position(false, vb[i].end,vb[i].hight));
            }
            return v;
        }
        
        
        
        
    };
    
    package advanced_class_04;
    
    import java.util.ArrayList;
    import java.util.Arrays;
    import java.util.Comparator;
    import java.util.List;
    import java.util.Map.Entry;
    import java.util.TreeMap;
    
    public class Code_01_Building_Outline {
    
    	public static class Node {
    		public boolean isUp;
    		public int posi;
    		public int h;
    
    		public Node(boolean bORe, int position, int height) {
    			isUp = bORe;
    			posi = position;
    			h = height;
    		}
    	}
    
    	public static class NodeComparator implements Comparator<Node> {
    		@Override
    		public int compare(Node o1, Node o2) {
    			if (o1.posi != o2.posi) {				
    				return o1.posi - o2.posi;
    			}
    			if (o1.isUp != o2.isUp) {
    				return o1.isUp ? -1 : 1;
    			}
    			return 0;
    		}
    	}
    
    	public static List<List<Integer>> buildingOutline(int[][] buildings) {
    		Node[] nodes = new Node[buildings.length * 2];
    		for (int i = 0; i < buildings.length; i++) {
    			nodes[i * 2] = new Node(true, buildings[i][0], buildings[i][2]);
    			nodes[i * 2 + 1] = new Node(false, buildings[i][1], buildings[i][2]);
    		}
    		Arrays.sort(nodes, new NodeComparator());
    		TreeMap<Integer, Integer> htMap = new TreeMap<>();
    		TreeMap<Integer, Integer> pmMap = new TreeMap<>();
    		for (int i = 0; i < nodes.length; i++) {
    			if (nodes[i].isUp) {
    				if (!htMap.containsKey(nodes[i].h)) {
    					htMap.put(nodes[i].h, 1);
    				} else {
    					htMap.put(nodes[i].h, htMap.get(nodes[i].h) + 1);
    				}
    			} else {
    				if (htMap.containsKey(nodes[i].h)) {
    					if (htMap.get(nodes[i].h) == 1) {
    						htMap.remove(nodes[i].h);
    					} else {
    						htMap.put(nodes[i].h, htMap.get(nodes[i].h) - 1);
    					}
    				}
    			}
    			if (htMap.isEmpty()) {
    				pmMap.put(nodes[i].posi, 0);
    			} else {
    				pmMap.put(nodes[i].posi, htMap.lastKey());
    			}
    		}
    		List<List<Integer>> res = new ArrayList<>();
    		int start = 0;
    		int height = 0;
    		for (Entry<Integer, Integer> entry : pmMap.entrySet()) {
    			int curPosition = entry.getKey();
    			int curMaxHeight = entry.getValue();
    			if (height != curMaxHeight) {
    				if (height != 0) {
    					List<Integer> newRecord = new ArrayList<Integer>();
    					newRecord.add(start);
    					newRecord.add(curPosition);
    					newRecord.add(height);
    					res.add(newRecord);
    				}
    				start = curPosition;
    				height = curMaxHeight;
    			}
    		}
    		return res;
    	}
    
    }
    
    1、对大楼信息进行处理 保存为三元组(上升/下降,坐标x,高度)。
    2、对三元组进行排序,排序的规则是按照坐标x 如果坐标x相同则再按照谁是上升沿处理。这样做的目的是为了保
    证某个坐标的上升沿一定先出现。
    3、遍历集合,根据上升沿和下降沿的信息,处理集合元素,用来获取当前最大高度信息。
    4、根据的到的高度信息,重新构建轮廓信息,(只要高度变化,那就会产生轮廓。)
    对于C++来说,map集合的使用相当重要,这里用下标访问的方式会更加的快捷。省去了不断的增删过程。

     

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值