Skip to content

Commit c38214d

Browse files
authored
feat: add solutions to lc problem: No.0218 (doocs#858)
No.0218.The Skyline Problem
1 parent f76db13 commit c38214d

File tree

4 files changed

+216
-9
lines changed

4 files changed

+216
-9
lines changed

solution/0200-0299/0218.The Skyline Problem/README.md

Lines changed: 75 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -55,22 +55,93 @@
5555

5656
<!-- 这里可写通用的实现逻辑 -->
5757

58+
**方法一:扫描线+优先队列**
59+
60+
记录下所有建筑物的左右边界线,升序排序之后得到序列 lines。对于每一个边界线 lines[i],找出所有包含 lines[i] 的建筑物,并确保建筑物的左边界小于等于 lines[i],右边界大于 lines[i],则这些建筑物中高度最高的建筑物的高度就是该线轮廓点的高度。可以使用建筑物的高度构建优先队列(大根堆),同时需要注意高度相同的轮廓点需要合并为一个。
61+
5862
<!-- tabs:start -->
5963

6064
### **Python3**
6165

6266
<!-- 这里可写当前语言的特殊实现逻辑 -->
6367

6468
```python
65-
69+
from queue import PriorityQueue
70+
71+
72+
class Solution:
73+
def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
74+
skys, lines, pq = [], [], PriorityQueue()
75+
for build in buildings:
76+
lines.extend([build[0], build[1]])
77+
lines.sort()
78+
city, n = 0, len(buildings)
79+
for line in lines:
80+
while city < n and buildings[city][0] <= line:
81+
pq.put([-buildings[city][2], buildings[city]
82+
[0], buildings[city][1]])
83+
city += 1
84+
while not pq.empty() and pq.queue[0][2] <= line:
85+
pq.get()
86+
high = 0
87+
if not pq.empty():
88+
high = -pq.queue[0][0]
89+
if len(skys) > 0 and skys[-1][1] == high:
90+
continue
91+
skys.append([line, high])
92+
return skys
6693
```
6794

68-
### **Java**
95+
### **Go**
6996

7097
<!-- 这里可写当前语言的特殊实现逻辑 -->
7198

72-
```java
73-
99+
```go
100+
type Matrix struct{ left, right, height int }
101+
type Queue []Matrix
102+
103+
func (q Queue) Len() int { return len(q) }
104+
func (q Queue) Top() Matrix { return q[0] }
105+
func (q Queue) Swap(i, j int) { q[i], q[j] = q[j], q[i] }
106+
func (q Queue) Less(i, j int) bool { return q[i].height > q[j].height }
107+
func (q *Queue) Push(x interface{}) { *q = append(*q, x.(Matrix)) }
108+
func (q *Queue) Pop() interface{} {
109+
old, x := *q, (*q)[len(*q)-1]
110+
*q = old[:len(old)-1]
111+
return x
112+
}
113+
114+
func getSkyline(buildings [][]int) [][]int {
115+
skys, lines, pq := make([][]int, 0), make([]int, 0), &Queue{}
116+
heap.Init(pq)
117+
for _, v := range buildings {
118+
lines = append(lines, v[0], v[1])
119+
}
120+
sort.Ints(lines)
121+
city, n := 0, len(buildings)
122+
for _, line := range lines {
123+
// 将所有符合条件的矩形加入队列
124+
for ; city < n && buildings[city][0] <= line && buildings[city][1] > line; city++ {
125+
v := Matrix{left: buildings[city][0], right: buildings[city][1], height: buildings[city][2]}
126+
heap.Push(pq, v)
127+
}
128+
// 从队列移除不符合条件的矩形
129+
for pq.Len() > 0 && pq.Top().right <= line {
130+
heap.Pop(pq)
131+
}
132+
high := 0
133+
// 队列为空说明是最右侧建筑物的终点,其轮廓点为 (line, 0)
134+
if pq.Len() != 0 {
135+
high = pq.Top().height
136+
}
137+
// 如果该点高度和前一个轮廓点一样的话,直接忽略
138+
if len(skys) > 0 && skys[len(skys)-1][1] == high {
139+
continue
140+
}
141+
skys = append(skys, []int{line, high})
142+
}
143+
return skys
144+
}
74145
```
75146

76147
### **C++**

solution/0200-0299/0218.The Skyline Problem/README_EN.md

Lines changed: 72 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -55,13 +55,80 @@ Figure B shows the skyline formed by those buildings. The red points in figure B
5555
### **Python3**
5656

5757
```python
58-
58+
from queue import PriorityQueue
59+
60+
61+
class Solution:
62+
def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
63+
skys, lines, pq = [], [], PriorityQueue()
64+
for build in buildings:
65+
lines.extend([build[0], build[1]])
66+
lines.sort()
67+
city, n = 0, len(buildings)
68+
for line in lines:
69+
while city < n and buildings[city][0] <= line:
70+
pq.put([-buildings[city][2], buildings[city]
71+
[0], buildings[city][1]])
72+
city += 1
73+
while not pq.empty() and pq.queue[0][2] <= line:
74+
pq.get()
75+
high = 0
76+
if not pq.empty():
77+
high = -pq.queue[0][0]
78+
if len(skys) > 0 and skys[-1][1] == high:
79+
continue
80+
skys.append([line, high])
81+
return skys
5982
```
6083

61-
### **Java**
62-
63-
```java
64-
84+
### **Go**
85+
86+
```go
87+
type Matrix struct{ left, right, height int }
88+
type Queue []Matrix
89+
90+
func (q Queue) Len() int { return len(q) }
91+
func (q Queue) Top() Matrix { return q[0] }
92+
func (q Queue) Swap(i, j int) { q[i], q[j] = q[j], q[i] }
93+
func (q Queue) Less(i, j int) bool { return q[i].height > q[j].height }
94+
func (q *Queue) Push(x interface{}) { *q = append(*q, x.(Matrix)) }
95+
func (q *Queue) Pop() interface{} {
96+
old, x := *q, (*q)[len(*q)-1]
97+
*q = old[:len(old)-1]
98+
return x
99+
}
100+
101+
func getSkyline(buildings [][]int) [][]int {
102+
skys, lines, pq := make([][]int, 0), make([]int, 0), &Queue{}
103+
heap.Init(pq)
104+
for _, v := range buildings {
105+
lines = append(lines, v[0], v[1])
106+
}
107+
sort.Ints(lines)
108+
city, n := 0, len(buildings)
109+
for _, line := range lines {
110+
// 将所有符合条件的矩形加入队列
111+
for ; city < n && buildings[city][0] <= line && buildings[city][1] > line; city++ {
112+
v := Matrix{left: buildings[city][0], right: buildings[city][1], height: buildings[city][2]}
113+
heap.Push(pq, v)
114+
}
115+
// 从队列移除不符合条件的矩形
116+
for pq.Len() > 0 && pq.Top().right <= line {
117+
heap.Pop(pq)
118+
}
119+
high := 0
120+
// 队列为空说明是最右侧建筑物的终点,其轮廓点为 (line, 0)
121+
if pq.Len() != 0 {
122+
high = pq.Top().height
123+
}
124+
// 如果该点高度和前一个轮廓点一样的话,直接忽略
125+
if len(skys) > 0 && skys[len(skys)-1][1] == high {
126+
continue
127+
}
128+
skys = append(skys, []int{line, high})
129+
}
130+
return skys
131+
}
65132
```
66133

67134
### **C++**
Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
type Matrix struct{ left, right, height int }
2+
type Queue []Matrix
3+
4+
func (q Queue) Len() int { return len(q) }
5+
func (q Queue) Top() Matrix { return q[0] }
6+
func (q Queue) Swap(i, j int) { q[i], q[j] = q[j], q[i] }
7+
func (q Queue) Less(i, j int) bool { return q[i].height > q[j].height }
8+
func (q *Queue) Push(x interface{}) { *q = append(*q, x.(Matrix)) }
9+
func (q *Queue) Pop() interface{} {
10+
old, x := *q, (*q)[len(*q)-1]
11+
*q = old[:len(old)-1]
12+
return x
13+
}
14+
15+
func getSkyline(buildings [][]int) [][]int {
16+
skys, lines, pq := make([][]int, 0), make([]int, 0), &Queue{}
17+
heap.Init(pq)
18+
for _, v := range buildings {
19+
lines = append(lines, v[0], v[1])
20+
}
21+
sort.Ints(lines)
22+
city, n := 0, len(buildings)
23+
for _, line := range lines {
24+
// 将所有符合条件的矩形加入队列
25+
for ; city < n && buildings[city][0] <= line && buildings[city][1] > line; city++ {
26+
v := Matrix{left: buildings[city][0], right: buildings[city][1], height: buildings[city][2]}
27+
heap.Push(pq, v)
28+
}
29+
// 从队列移除不符合条件的矩形
30+
for pq.Len() > 0 && pq.Top().right <= line {
31+
heap.Pop(pq)
32+
}
33+
high := 0
34+
// 队列为空说明是最右侧建筑物的终点,其轮廓点为 (line, 0)
35+
if pq.Len() != 0 {
36+
high = pq.Top().height
37+
}
38+
// 如果该点高度和前一个轮廓点一样的话,直接忽略
39+
if len(skys) > 0 && skys[len(skys)-1][1] == high {
40+
continue
41+
}
42+
skys = append(skys, []int{line, high})
43+
}
44+
return skys
45+
}
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
from queue import PriorityQueue
2+
3+
4+
class Solution:
5+
def getSkyline(self, buildings: List[List[int]]) -> List[List[int]]:
6+
skys, lines, pq = [], [], PriorityQueue()
7+
for build in buildings:
8+
lines.extend([build[0], build[1]])
9+
lines.sort()
10+
city, n = 0, len(buildings)
11+
for line in lines:
12+
while city < n and buildings[city][0] <= line:
13+
pq.put([-buildings[city][2], buildings[city]
14+
[0], buildings[city][1]])
15+
city += 1
16+
while not pq.empty() and pq.queue[0][2] <= line:
17+
pq.get()
18+
high = 0
19+
if not pq.empty():
20+
high = -pq.queue[0][0]
21+
if len(skys) > 0 and skys[-1][1] == high:
22+
continue
23+
skys.append([line, high])
24+
return skys

0 commit comments

Comments
 (0)