水平面上有 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] ]
-
// // 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集合的使用相当重要,这里用下标访问的方式会更加的快捷。省去了不断的增删过程。