Skip to content

Commit 3ae1cd3

Browse files
committed
leetcode
1 parent d6dcf04 commit 3ae1cd3

File tree

4 files changed

+630
-0
lines changed

4 files changed

+630
-0
lines changed

README.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,7 @@ This repo contain leetcode solution using DART and GO programming language. Most
6161
- [Find K Closest Elements](FindKClosestElements/find_k_closest_elements.dart)
6262
- [Excel Sheet Column Title](ExcelSheetColumnTitle/excel_sheet_column_title.dart)
6363
- [Majority Element](MajorityElement/majority_element.dart)
64+
- [The Skyline Problem](TheSkylineProblem/the_skyline_problem.dart)
6465

6566
## Reach me via
6667

Lines changed: 313 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,313 @@
1+
/*
2+
3+
-* The Skyline Problem *-
4+
5+
6+
A city's skyline is the outer contour of the silhouette formed by all the buildings in that city when viewed from a distance. Given the locations and heights of all the buildings, return the skyline formed by these buildings collectively.
7+
8+
The geometric information of each building is given in the array buildings where buildings[i] = [lefti, righti, heighti]:
9+
10+
left-i is the x coordinate of the left edge of the ith building.
11+
right-i is the x coordinate of the right edge of the ith building.
12+
height-i is the height of the ith building.
13+
You may assume all buildings are perfect rectangles grounded on an absolutely flat surface at height 0.
14+
15+
The skyline should be represented as a list of "key points" sorted by their x-coordinate in the form [[x1,y1],[x2,y2],...]. Each key point is the left endpoint of some horizontal segment in the skyline except the last point in the list, which always has a y-coordinate 0 and is used to mark the skyline's termination where the rightmost building ends. Any ground between the leftmost and rightmost buildings should be part of the skyline's contour.
16+
17+
Note: There must be no consecutive horizontal lines of equal height in the output skyline. For instance, [...,[2 3],[4 5],[7 5],[11 5],[12 7],...] is not acceptable; the three lines of height 5 should be merged into one in the final output as such: [...,[2 3],[4 5],[12 7],...]
18+
19+
20+
21+
Example 1:
22+
23+
24+
Input: buildings = [[2,9,10],[3,7,15],[5,12,12],[15,20,10],[19,24,8]]
25+
Output: [[2,10],[3,15],[7,12],[12,0],[15,10],[20,8],[24,0]]
26+
Explanation:
27+
Figure A shows the buildings of the input.
28+
Figure B shows the skyline formed by those buildings. The red points in figure B represent the key points in the output list.
29+
Example 2:
30+
31+
Input: buildings = [[0,2,3],[2,5,3]]
32+
Output: [[0,3],[5,0]]
33+
34+
35+
Constraints:
36+
37+
1 <= buildings.length <= 104
38+
0 <= left-i < right-i <= 231 - 1
39+
1 <= height-i <= 231 - 1
40+
buildings is sorted by left-i in non-decreasing order.
41+
42+
43+
44+
45+
*/
46+
47+
import 'dart:math';
48+
49+
class A {
50+
List<List<int>> getSkyline(List<List<int>> buildings) {
51+
int n = buildings.length;
52+
List<int> keys = [];
53+
for (List<int> building in buildings) {
54+
keys.add(building[0]);
55+
keys.add(building[1]);
56+
}
57+
keys.sort();
58+
int last = 0;
59+
int lastKey = -1;
60+
List<int> temp = [];
61+
List<List<int>> result = [].map((e) => <int>[]).toList();
62+
for (int left in keys) {
63+
if (left == lastKey) continue;
64+
lastKey = left;
65+
int height = 0;
66+
for (List<int> building in buildings) {
67+
if (left >= building[0] && left < building[1])
68+
height = max(height, building[2]);
69+
else if (building[0] > left) break;
70+
}
71+
if (height != last) {
72+
temp.add(left);
73+
temp.add(height);
74+
result.add(temp);
75+
temp.clear();
76+
}
77+
last = height;
78+
}
79+
return result;
80+
}
81+
}
82+
83+
class C {
84+
// Time Limit exceed
85+
List<List<int>> getSkyline(List<List<int>> buildings) {
86+
Set new_set = Set();
87+
buildings.forEach((b) {
88+
new_set.add(b[0]);
89+
new_set.add(b[1]);
90+
});
91+
List temp = List.from(new_set);
92+
temp.sort((a, b) => a - b);
93+
List<List<int>> result = [].map((e) => <int>[]).toList();
94+
temp.forEach((x) {
95+
List<List<int>> b =
96+
buildings.where((b) => b[0] == x || b[0] < x && b[1] > x).toList();
97+
int maxi = 0;
98+
for (int i = 0; i < b.length; i++) {
99+
maxi = max(maxi, b[i][2]);
100+
}
101+
result.add([x, maxi]);
102+
});
103+
104+
for (int i = 1; i < result.length; i++) {
105+
List<int> last = result[i - 1];
106+
List<int> current = result[i];
107+
if (last[1] == current[1]) {
108+
result.sublist(1, i);
109+
i--;
110+
}
111+
}
112+
return result;
113+
}
114+
}
115+
116+
class KeyPoint {
117+
int key;
118+
int height;
119+
KeyPoint? next = null;
120+
121+
KeyPoint(int this.key, int this.height);
122+
}
123+
124+
class D {
125+
// Runtime: 592 ms, faster than 100.00% of Dart online submissions for The Skyline Problem.
126+
// Memory Usage: 147.5 MB, less than 100.00% of Dart online submissions for The Skyline Problem.
127+
128+
List<List<int>> getSkyline(List<List<int>> buildings) {
129+
List<List<int>> res = [].map((e) => <int>[]).toList();
130+
KeyPoint dummy = KeyPoint(-1, 0); // dummy head
131+
KeyPoint pre = dummy;
132+
133+
for (List<int> bd in buildings) {
134+
int L = bd[0];
135+
int R = bd[1];
136+
int H = bd[2];
137+
138+
while (pre.next != null && pre.next!.key <= L) pre = pre.next!;
139+
140+
int preH = pre.height;
141+
142+
if (pre.key == L)
143+
pre.height = max(pre.height, H);
144+
else if (pre.height < H) {
145+
KeyPoint? next = pre.next;
146+
pre.next = new KeyPoint(L, H);
147+
pre = pre.next!;
148+
pre.next = next;
149+
}
150+
151+
KeyPoint preIter = pre;
152+
KeyPoint? curIter = pre.next;
153+
while (curIter != null && curIter.key < R) {
154+
preH = curIter.height;
155+
curIter.height = max(curIter.height, H);
156+
157+
if (curIter.height == preIter.height)
158+
preIter.next = curIter.next;
159+
else
160+
preIter = curIter;
161+
162+
curIter = curIter.next;
163+
}
164+
165+
if (preIter.height != preH &&
166+
preIter.key != R &&
167+
(curIter == null || curIter.key != R)) {
168+
KeyPoint? next = preIter.next;
169+
preIter.next = KeyPoint(R, preH);
170+
preIter.next!.next = next;
171+
}
172+
}
173+
174+
KeyPoint? first = dummy;
175+
KeyPoint? second = dummy.next;
176+
while (second != null) {
177+
if (second.height != first!.height)
178+
//res.add(Arrays.asList(second.key, second.height));
179+
res.add([second.key, second.height]);
180+
first = first.next;
181+
second = second.next;
182+
}
183+
return res;
184+
}
185+
}
186+
187+
class E {
188+
// divide and conquer
189+
// Runtime: 498 ms, faster than 100.00% of Dart online submissions for The Skyline Problem.
190+
// Memory Usage: 152 MB, less than 100.00% of Dart online submissions for The Skyline Problem.
191+
192+
List<List<int>> getSkyline(List<List<int>> buildings) {
193+
List<List<int>> res = [].map((e) => <int>[]).toList();
194+
if (buildings.length == 0) return res;
195+
int n = buildings.length;
196+
return findSkyline(buildings, 0, n - 1);
197+
}
198+
199+
List<List<int>> findSkyline(List<List<int>> buildings, int lo, int hi) {
200+
List<List<int>> res = [].map((e) => <int>[]).toList();
201+
;
202+
if (lo == hi) {
203+
res.add([buildings[lo][0], buildings[lo][2]]);
204+
res.add([buildings[lo][1], 0]);
205+
return res;
206+
}
207+
int mid = lo + (hi - lo) ~/ 2;
208+
List<List<int>> skyline1 = findSkyline(buildings, lo, mid);
209+
List<List<int>> skyline2 = findSkyline(buildings, mid + 1, hi);
210+
return mergeSkyline(skyline1, skyline2);
211+
}
212+
213+
List<List<int>> mergeSkyline(
214+
List<List<int>> skyline1, List<List<int>> skyline2) {
215+
List<List<int>> res = [].map((e) => <int>[]).toList();
216+
int i = 0, j = 0;
217+
int h1 = 0, h2 = 0;
218+
219+
while (i < skyline1.length && j < skyline2.length) {
220+
int x1 = skyline1.elementAt(i).elementAt(0);
221+
int x2 = skyline2.elementAt(j).elementAt(0);
222+
int x;
223+
if (x1 < x2) {
224+
h1 = skyline1.elementAt(i++).elementAt(1);
225+
x = x1;
226+
} else if (x1 > x2) {
227+
h2 = skyline2.elementAt(j++).elementAt(1);
228+
x = x2;
229+
} else {
230+
h1 = skyline1.elementAt(i++).elementAt(1);
231+
h2 = skyline2.elementAt(j++).elementAt(1);
232+
x = x1;
233+
}
234+
int h = max(h1, h2);
235+
236+
if (res.isEmpty || h != res.elementAt(res.length - 1).elementAt(1)) {
237+
res.add([x, h]);
238+
}
239+
}
240+
241+
while (i < skyline1.length) res.add(skyline1.elementAt(i++));
242+
while (j < skyline2.length) res.add(skyline2.elementAt(j++));
243+
244+
return res;
245+
}
246+
}
247+
248+
class F {
249+
// Runtime: 835 ms, faster than 100.00% of Dart online submissions for The Skyline Problem.
250+
// Memory Usage: 151.5 MB, less than 100.00% of Dart online submissions for The Skyline Problem.
251+
252+
List<List<int>> getSkyline(List<List<int>> buildings) {
253+
if (buildings.length == 0) return [].map((e) => <int>[]).toList();
254+
return recurSkyline(buildings, 0, buildings.length - 1);
255+
}
256+
257+
List<List<int>> recurSkyline(List<List<int>> buildings, int p, int q) {
258+
if (p < q) {
259+
int mid = p + (q - p) ~/ 2;
260+
return merge(
261+
recurSkyline(buildings, p, mid), recurSkyline(buildings, mid + 1, q));
262+
} else {
263+
List<List<int>> rs = [].map((e) => <int>[]).toList();
264+
rs.add([buildings[p][0], buildings[p][2]]);
265+
rs.add([buildings[p][1], 0]);
266+
return rs;
267+
}
268+
}
269+
270+
List<List<int>> merge(List<List<int>> l1, List<List<int>> l2) {
271+
List<List<int>> rs = [].map((e) => <int>[]).toList();
272+
int h1 = 0, h2 = 0;
273+
while (l1.length > 0 && l2.length > 0) {
274+
int x = 0, h = 0;
275+
if (l1.first[0] < l2.first[0]) {
276+
x = l1.first[0];
277+
h1 = l1.first[1];
278+
h = max(h1, h2);
279+
// remove first
280+
l1.removeAt(0);
281+
} else if (l1.first[0] > l2.first[0]) {
282+
x = l2.first[0];
283+
h2 = l2.first[1];
284+
h = max(h1, h2);
285+
l2.removeAt(0);
286+
} else {
287+
x = l1.first[0];
288+
h1 = l1.first[1];
289+
h2 = l2.first[1];
290+
h = max(h1, h2);
291+
l1.removeAt(0);
292+
l2.removeAt(0);
293+
}
294+
if (rs.length == 0 || h != rs.last[1]) {
295+
rs.add([x, h]);
296+
}
297+
}
298+
rs.addAll(l1);
299+
rs.addAll(l2);
300+
return rs;
301+
}
302+
}
303+
304+
extension Splice<T> on List<T> {
305+
List<T> splice<T>(List<T> list, int index,
306+
[num howMany = 0, /*<T | List<T>>*/ elements]) {
307+
var endIndex = index + howMany.truncate();
308+
list.removeRange(index, endIndex >= list.length ? list.length : endIndex);
309+
if (elements != null)
310+
list.insertAll(index, elements is List<T> ? elements : <T>[elements]);
311+
return list;
312+
}
313+
}

0 commit comments

Comments
 (0)