-
Notifications
You must be signed in to change notification settings - Fork 5
/
Copy pathBuilding Outline - Solution I.java
114 lines (109 loc) · 4.46 KB
/
Building Outline - Solution I.java
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
public class Solution {
/**
* @param buildings: A list of lists of integers
* @return: Find the outline of those buildings
*/
private static class Rectangle {
public int left, right, height;
public Rectangle(int left, int right, int height) {
this.left = left;
this.right = right;
this.height = height;
}
}
private static class Ref<T> {
public T value;
public Ref(T v) {
value = v;
}
}
public ArrayList<ArrayList<Integer>> buildingOutline(int[][] buildings) {
// write your code here
List<Rectangle> list = new ArrayList<Rectangle>();
for (int i = 0; i < buildings.length; i++) {
list.add(new Rectangle(buildings[i][0], buildings[i][1], buildings[i][2]));
}
List<Rectangle> rst = computeSkylineInInterval(list, 0, list.size());
ArrayList<ArrayList<Integer>> output = new ArrayList<ArrayList<Integer>>();
for (Rectangle r : rst) {
ArrayList<Integer> items = new ArrayList<Integer>();
items.add(r.left);
items.add(r.right);
items.add(r.height);
output.add(items);
}
return output;
}
private static List<Rectangle> computeSkylineInInterval( List<Rectangle> buildings, int leftEndpoint, int rightEndpoint) {
if (rightEndpoint - leftEndpoint <= 1) { // 0 or 1 skyline, just copy it.
return new ArrayList<>(buildings.subList(leftEndpoint, rightEndpoint));
}
int mid = leftEndpoint + ((rightEndpoint - leftEndpoint) / 2);
List<Rectangle> leftSkyline
= computeSkylineInInterval(buildings, leftEndpoint, mid);
List<Rectangle> rightSkyline
= computeSkylineInInterval(buildings, mid, rightEndpoint);
return mergeSkylines(leftSkyline, rightSkyline);
}
private static List<Rectangle> mergeSkylines(List<Rectangle> leftSkyline,
List<Rectangle> rightSkyline) {
int i = 0, j = 0;
List<Rectangle> merged = new ArrayList<>();
while (i < leftSkyline.size() && j < rightSkyline.size()) {
if (leftSkyline.get(i).right < rightSkyline.get(j).left) {
merged.add(leftSkyline.get(i++));
} else if (rightSkyline.get(j).right < leftSkyline.get(i).left) {
merged.add(rightSkyline.get(j++));
} else if (leftSkyline.get(i).left <= rightSkyline.get(j).left) {
Ref<Integer> iWrapper = new Ref<Integer>(i);
Ref<Integer> jWrapper = new Ref<Integer>(j);
mergeIntersectSkylines(merged, leftSkyline.get(i), iWrapper, rightSkyline.get(j), jWrapper);
i = iWrapper.value;
j = jWrapper.value;
} else { // leftSkyline.get(i).left > rightSkyline.get(j).left.
Ref<Integer> iWrapper = new Ref<>(i);
Ref<Integer> jWrapper = new Ref<>(j);
mergeIntersectSkylines(merged, rightSkyline.get(j), jWrapper, leftSkyline.get(i), iWrapper);
i = iWrapper.value;
j = jWrapper.value;
}
}
merged.addAll(leftSkyline.subList(i, leftSkyline.size()));
merged.addAll(rightSkyline.subList(j, rightSkyline.size()));
return merged;
}
private static void mergeIntersectSkylines(List<Rectangle> merged, Rectangle a,
Ref<Integer> aIdx, Rectangle b,
Ref<Integer> bIdx) {
if (a.right <= b.right) {
if (a.height > b.height) {
if (b.right != a.right) {
merged.add(a);
aIdx.value = aIdx.value + 1;
b.left = a.right;
} else {
bIdx.value = bIdx.value + 1;
}
} else if (a.height == b.height) {
b.left = a.left;
aIdx.value = aIdx.value + 1;
} else { // a->height < b->height.
if (a.left != b.left) {
merged.add(new Rectangle(a.left, b.left, a.height));
}
aIdx.value = aIdx.value + 1;
}
} else { // a.right > b.right.
if (a.height >= b.height) {
bIdx.value = bIdx.value + 1;
} else {
if (a.left != b.left) {
merged.add(new Rectangle(a.left, b.left, a.height));
}
a.left = b.right;
merged.add(b);
bIdx.value = bIdx.value + 1;
}
}
}
}