大楼轮廓问题
给定一个N \times 3N×3的矩阵matrix,对于每一个长度为3的小数组arr,都表示一个大楼的三个数据。arr[0]表示大楼的左边界,arr[1]表示大楼的右边界,arr[2]表示大楼的高度(一定大于0)。每座大楼的地基都在X轴上,大楼之间可能会有重叠,请返回整体的轮廓线数组
[要求]时间复杂度为O(n \log n)O(nlogn)
输入:给定一个二维数组[[1,3,3],[2,4,4],[5,6,1]]
输出轮廓线:[[1,2,3],[2,4,4],[5,6,1]]
package cao;
import java.util.*;
public class hello {
//定义红黑树节点:把一组输入值拆分成两个节点
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>> buildoutline(int[][] buildings){
//buildings.length大楼的数量
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;
//位置小的先遍历,利用pmMap找出所有轮廓线
for(Map.Entry<Integer,Integer> entry :pmMap.entrySet()){
int curPosition=entry.getKey();
int curmaxheight=entry.getValue();
if(height!=curmaxheight){
//根据height!=0来判断是否开始
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;
}
public static void main(String[] args) {
int[][] build={{1,3,3},{2,4,4},{5,6,1}};
List<List<Integer>> res=new ArrayList<>();
res=buildoutline(build);
for(int i=0;i<res.size();i++){
for(int j=0;j<res.get(i).size();j++){
System.out.println(res.get(i).get(j));
}
}
}
}