ICode9

精准搜索请尝试: 精确搜索
首页 > 其他分享> 文章详细

【LeetCode/LintCode】 题解丨微软面试题:大楼轮廓

2020-08-07 13:32:03  阅读:322  来源: 互联网

标签:面试题 return get int 题解 LintCode heap now id


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

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

点击进入在线评测

样例1

输入:
[
[1, 3, 3],
[2, 4, 4],
[5, 6, 1]
]
输出:
[
[1, 2, 3],
[2, 4, 4],
[5, 6, 1]
]
说明:
建筑物如下图所示,黄色部分表示建筑物

样例2

输入:
[
[1, 4, 3],
[6, 9, 5]
]
输出:
[
[1, 4, 3],
[6, 9, 5]
]
说明:
建筑物如下图所示,黄色部分表示建筑物

【题解】

使用[九章算法强化班]中讲过的 HashHeap 和扫描线算法。 Java 可以用 TreeSet / TreeMap, C++ 可以用 Map.

import java.util.*;

public class Solution {

class HashHeap {
ArrayList<Integer> heap;
String mode;
int size_t;
HashMap<Integer, Node> hash;

class Node {
public Integer id;
public Integer num;

Node(Node now) {
id = now.id;
num = now.num;
}

Node(Integer first, Integer second) {

this.id = first;
this.num = second;
}
}

public HashHeap(String mod) {
// TODO Auto-generated constructor stub
heap = new ArrayList<Integer>();
mode = mod;
hash = new HashMap<Integer, Node>();
size_t = 0;
}

public int peek() {
return heap.get(0);
}

public int size() {
return size_t;
}

public Boolean isEmpty() {
return (heap.size() == 0);
}

int parent(int id) {
if (id == 0) {
return -1;
}
return (id - 1) / 2;
}

int lson(int id) {
return id * 2 + 1;
}

int rson(int id) {
return id * 2 + 2;
}

boolean comparesmall(int a, int b) {
if (a <= b) {
if (mode == "min")
return true;
else
return false;
} else {
if (mode == "min")
return false;
else
return true;
}

}

void swap(int idA, int idB) {
int valA = heap.get(idA);
int valB = heap.get(idB);

int numA = hash.get(valA).num;
int numB = hash.get(valB).num;
hash.put(valB, new Node(idA, numB));
hash.put(valA, new Node(idB, numA));
heap.set(idA, valB);
heap.set(idB, valA);
}

public Integer poll() {
size_t--;
Integer now = heap.get(0);
Node hashnow = hash.get(now);
if (hashnow.num == 1) {
swap(0, heap.size() - 1);
hash.remove(now);
heap.remove(heap.size() - 1);
if (heap.size() > 0) {
siftdown(0);
}
} else {
hash.put(now, new Node(0, hashnow.num - 1));
}
return now;
}

public void add(int now) {
size_t++;
if (hash.containsKey(now)) {
Node hashnow = hash.get(now);
hash.put(now, new Node(hashnow.id, hashnow.num + 1));

} else {
heap.add(now);
hash.put(now, new Node(heap.size() - 1, 1));
}

siftup(heap.size() - 1);
}

public void delete(int now) {
size_t--;
Node hashnow = hash.get(now);
int id = hashnow.id;
int num = hashnow.num;
if (hashnow.num == 1) {

swap(id, heap.size() - 1);
hash.remove(now);
heap.remove(heap.size() - 1);
if (heap.size() > id) {
siftup(id);
siftdown(id);
}
} else {
hash.put(now, new Node(id, num - 1));
}
}

void siftup(int id) {
while (parent(id) > -1) {
int parentId = parent(id);
if (comparesmall(heap.get(parentId), heap.get(id)) == true) {
break;
} else {
swap(id, parentId);
}
id = parentId;
}
}

void siftdown(int id) {
while (lson(id) < heap.size()) {
int leftId = lson(id);
int rightId = rson(id);
int son;
if (rightId >= heap.size()
|| (comparesmall(heap.get(leftId), heap.get(rightId)) == true)) {
son = leftId;
} else {
son = rightId;
}
if (comparesmall(heap.get(id), heap.get(son)) == true) {
break;
} else {
swap(id, son);
}
id = son;
}
}
}

class Edge {
int pos;
int height;
boolean isStart;

public Edge(int pos, int height, boolean isStart) {
this.pos = pos;
this.height = height;
this.isStart = isStart;
}

}

class EdgeComparator implements Comparator<Edge> {
@Override
public int compare(Edge arg1, Edge arg2) {
Edge l1 = (Edge) arg1;
Edge l2 = (Edge) arg2;
if (l1.pos != l2.pos)
return compareInteger(l1.pos, l2.pos);
if (l1.isStart && l2.isStart) {
return compareInteger(l2.height, l1.height);
}
if (!l1.isStart && !l2.isStart) {
return compareInteger(l1.height, l2.height);
}
return l1.isStart ? -1 : 1;
}

int compareInteger(int a, int b) {
return a <= b ? -1 : 1;
}
}

List<List<Integer>> output(List<List<Integer>> res) {
List<List<Integer>> ans = new ArrayList<List<Integer>>();
if (res.size() > 0) {
int pre = res.get(0).get(0);
int height = res.get(0).get(1);
for (int i = 1; i < res.size(); i++) {
List<Integer> now = new ArrayList<Integer>();
int id = res.get(i).get(0);
if (height > 0) {
now.add(pre);
now.add(id);
now.add(height);
ans.add(now);
}
pre = id;
height = res.get(i).get(1);
}
}
return ans;
}

public List<List<Integer>> buildingOutline(int[][] buildings) {
// write your code here
List<List<Integer>> res = new ArrayList<List<Integer>>();

if (buildings == null || buildings.length == 0
|| buildings[0].length == 0) {
return res;
}
ArrayList<Edge> edges = new ArrayList<Edge>();
for (int[] building : buildings) {
Edge startEdge = new Edge(building[0], building[2], true);
edges.add(startEdge);
Edge endEdge = new Edge(building[1], building[2], false);
edges.add(endEdge);
}
Collections.sort(edges, new EdgeComparator());

HashHeap heap = new HashHeap("max");

List<Integer> now = null;
for (Edge edge : edges) {
if (edge.isStart) {
if (heap.isEmpty() || edge.height > heap.peek()) {
now = new ArrayList<Integer>(Arrays.asList(edge.pos,
edge.height));
res.add(now);
}
heap.add(edge.height);
} else {
heap.delete(edge.height);
if (heap.isEmpty() || edge.height > heap.peek()) {
if (heap.isEmpty()) {
now = new ArrayList<Integer>(Arrays.asList(edge.pos, 0));
} else {
now = new ArrayList<Integer>(Arrays.asList(edge.pos,
heap.peek()));
}
res.add(now);
}
}
}
return output(res);
}

}
更多题解参见:九章官网

标签:面试题,return,get,int,题解,LintCode,heap,now,id
来源: https://www.cnblogs.com/lintcode/p/13452279.html

本站声明: 1. iCode9 技术分享网(下文简称本站)提供的所有内容,仅供技术学习、探讨和分享;
2. 关于本站的所有留言、评论、转载及引用,纯属内容发起人的个人观点,与本站观点和立场无关;
3. 关于本站的所有言论和文字,纯属内容发起人的个人观点,与本站观点和立场无关;
4. 本站文章均是网友提供,不完全保证技术分享内容的完整性、准确性、时效性、风险性和版权归属;如您发现该文章侵犯了您的权益,可联系我们第一时间进行删除;
5. 本站为非盈利性的个人网站,所有内容不会用来进行牟利,也不会利用任何形式的广告来间接获益,纯粹是为了广大技术爱好者提供技术内容和技术思想的分享性交流网站。

专注分享技术,共同学习,共同进步。侵权联系[81616952@qq.com]

Copyright (C)ICode9.com, All Rights Reserved.

ICode9版权所有