Skip to content

Commit 6ea8b22

Browse files
refactor 218
1 parent 09b30ab commit 6ea8b22

File tree

1 file changed

+81
-68
lines changed
  • src/main/java/com/fishercoder/solutions

1 file changed

+81
-68
lines changed

src/main/java/com/fishercoder/solutions/_218.java

Lines changed: 81 additions & 68 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,25 @@
44
import java.util.Arrays;
55
import java.util.List;
66
import java.util.TreeMap;
7-
/**A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A), write a program to output the skyline formed by these buildings collectively (Figure B).
7+
/**
8+
* 218. The Skyline Problem
89
*
9-
* The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi], where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively, and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0. You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.
10-
11-
For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .
12-
13-
The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ] that uniquely defines a skyline. A key point is the left endpoint of a horizontal line segment. Note that the last key point, where the rightmost building ends, is merely used to mark the termination of the skyline, and always has zero height. Also, the ground in between any two adjacent buildings should be considered part of the skyline contour.
10+
* A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance.
11+
* Now suppose you are given the locations and height of all the buildings as shown on a cityscape photo (Figure A),
12+
* write a program to output the skyline formed by these buildings collectively (Figure B).
13+
*
14+
* The geometric information of each building is represented by a triplet of integers [Li, Ri, Hi],
15+
* where Li and Ri are the x coordinates of the left and right edge of the ith building, respectively,
16+
* and Hi is its height. It is guaranteed that 0 ≤ Li, Ri ≤ INT_MAX, 0 < Hi ≤ INT_MAX, and Ri - Li > 0.
17+
* You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.
18+
*
19+
* For instance, the dimensions of all buildings in Figure A are recorded as: [ [2 9 10], [3 7 15], [5 12 12], [15 20 10], [19 24 8] ] .
20+
* The output is a list of "key points" (red dots in Figure B) in the format of [ [x1,y1], [x2, y2], [x3, y3], ... ]
21+
* that uniquely defines a skyline.
22+
* A key point is the left endpoint of a horizontal line segment.
23+
* Note that the last key point, where the rightmost building ends,
24+
* is merely used to mark the termination of the skyline, and always has zero height.
25+
* Also, the ground in between any two adjacent buildings should be considered part of the skyline contour.
1426
1527
For instance, the skyline in Figure B should be represented as:[ [2 10], [3 15], [7 12], [12 0], [15 10], [20 8], [24, 0] ].
1628
@@ -30,91 +42,92 @@
3042
whenever we encounter the start of a building, we push it into the PriorityQueue, whenever we finished scanning that building, we remove it from the PriorityQueue
3143
Also, in the scan process, we’ll keep updating the maxHeight in the PriorityQueue if we find a new maxHeight which means the building will be overshadowed by the new higher one
3244
33-
3445
Three edge cases (see the graph illustration in the above video at 12’18”):
3546
when two buildings have the same start point, the one with higher height shows up in the final result
3647
when two buildings have the same end point, the one with higher height shows up in the final result
3748
when the start point of one building is is also the end point of another building, the one with higher height shows up in the final result
38-
3949
4050
We use TreeMap over a normal PriorityQueue:
41-
For the sake of efficiency (better time complexity), we’ll use TreeMap which supports O(logn) for remove() operation, this is the reason we choose TreeMap over a normal PriorityQueue in Java (PriorityQueue supports add() and getMaxVal() in both O(logn) time, however, for remove(), it does NOT.)
51+
For the sake of efficiency (better time complexity), we’ll use TreeMap which supports O(logn) for remove() operation,
52+
this is the reason we choose TreeMap over a normal PriorityQueue in Java (PriorityQueue supports add() and getMaxVal() in both O(logn) time, however, for remove(), it does NOT.)
4253
But TreeMap in Java supports all the three operations in O(logn) time.*/
4354

4455
public class _218 {
4556

46-
class BuildingPoint implements Comparable<BuildingPoint> {
47-
int x;
48-
boolean isStart;
49-
int h;
57+
public static class Solution1 {
5058

51-
public BuildingPoint(int x, boolean isStart, int h) {
52-
this.x = x;
53-
this.h = h;
54-
this.isStart = isStart;
55-
}
59+
class BuildingPoint implements Comparable<BuildingPoint> {
60+
int x;
61+
boolean isStart;
62+
int h;
63+
64+
public BuildingPoint(int x, boolean isStart, int h) {
65+
this.x = x;
66+
this.h = h;
67+
this.isStart = isStart;
68+
}
5669

57-
@Override
58-
public int compareTo(BuildingPoint o) {
59-
if (this.x != o.x) {
60-
return this.x - o.x;
61-
} else {
62-
if (this.isStart && o.isStart) {
63-
return o.h - this.h;
64-
} else if (this.isStart && !o.isStart) {
65-
return -this.h - o.h;
66-
} else if (!this.isStart && !o.isStart) {
67-
return this.h - o.h;
70+
@Override
71+
public int compareTo(BuildingPoint o) {
72+
if (this.x != o.x) {
73+
return this.x - o.x;
6874
} else {
69-
return this.h + o.h;
75+
if (this.isStart && o.isStart) {
76+
return o.h - this.h;
77+
} else if (this.isStart && !o.isStart) {
78+
return -this.h - o.h;
79+
} else if (!this.isStart && !o.isStart) {
80+
return this.h - o.h;
81+
} else {
82+
return this.h + o.h;
83+
}
7084
}
7185
}
7286
}
73-
}
7487

75-
public List<int[]> getSkyline(int[][] buildings) {
76-
BuildingPoint[] bps = new BuildingPoint[buildings.length * 2];
77-
int index = 0;
78-
for (int[] building : buildings) {
79-
BuildingPoint bp1 = new BuildingPoint(building[0], true, building[2]);
80-
BuildingPoint bp2 = new BuildingPoint(building[1], false, building[2]);
81-
bps[index++] = bp1;
82-
bps[index++] = bp2;
83-
}
88+
public List<int[]> getSkyline(int[][] buildings) {
89+
BuildingPoint[] bps = new BuildingPoint[buildings.length * 2];
90+
int index = 0;
91+
for (int[] building : buildings) {
92+
BuildingPoint bp1 = new BuildingPoint(building[0], true, building[2]);
93+
BuildingPoint bp2 = new BuildingPoint(building[1], false, building[2]);
94+
bps[index++] = bp1;
95+
bps[index++] = bp2;
96+
}
8497

85-
//this is one key step:
86-
Arrays.sort(bps);
87-
88-
List<int[]> result = new ArrayList();
89-
TreeMap<Integer, Integer> treeMap = new TreeMap();
90-
treeMap.put(0, 1);
91-
int prevMaxH = 0;
92-
for (BuildingPoint bp : bps) {
93-
//if it's a starting point, we'll add it into the final result
94-
if (bp.isStart) {
95-
if (treeMap.containsKey(bp.h)) {
96-
treeMap.put(bp.h, treeMap.get(bp.h) + 1);
97-
} else {
98-
treeMap.put(bp.h, 1);
98+
//this is one key step:
99+
Arrays.sort(bps);
100+
101+
List<int[]> result = new ArrayList();
102+
TreeMap<Integer, Integer> treeMap = new TreeMap();
103+
treeMap.put(0, 1);
104+
int prevMaxH = 0;
105+
for (BuildingPoint bp : bps) {
106+
//if it's a starting point, we'll add it into the final result
107+
if (bp.isStart) {
108+
if (treeMap.containsKey(bp.h)) {
109+
treeMap.put(bp.h, treeMap.get(bp.h) + 1);
110+
} else {
111+
treeMap.put(bp.h, 1);
112+
}
113+
} else if (!bp.isStart) {
114+
//if it's an ending point, we'll decrement/remove this entry
115+
if (treeMap.containsKey(bp.h) && treeMap.get(bp.h) > 1) {
116+
treeMap.put(bp.h, treeMap.get(bp.h) - 1);
117+
} else {
118+
treeMap.remove(bp.h);
119+
}
99120
}
100-
} else if (!bp.isStart) {
101-
//if it's an ending point, we'll decrement/remove this entry
102-
if (treeMap.containsKey(bp.h) && treeMap.get(bp.h) > 1) {
103-
treeMap.put(bp.h, treeMap.get(bp.h) - 1);
104-
} else {
105-
treeMap.remove(bp.h);
121+
122+
int currMaxH = treeMap.lastKey();
123+
if (currMaxH != prevMaxH) {
124+
result.add(new int[]{bp.x, currMaxH});
125+
prevMaxH = currMaxH;
106126
}
107-
}
108127

109-
int currMaxH = treeMap.lastKey();
110-
if (currMaxH != prevMaxH) {
111-
result.add(new int[]{bp.x, currMaxH});
112-
prevMaxH = currMaxH;
113128
}
114129

130+
return result;
115131
}
116-
117-
return result;
118132
}
119-
120133
}

0 commit comments

Comments
 (0)
pFad - Phonifier reborn

Pfad - The Proxy pFad of © 2024 Garber Painting. All rights reserved.

Note: This service is not intended for secure transactions such as banking, social media, email, or purchasing. Use at your own risk. We assume no liability whatsoever for broken pages.


Alternative Proxies:

Alternative Proxy

pFad Proxy

pFad v3 Proxy

pFad v4 Proxy