This repository was archived by the owner on Sep 20, 2023. It is now read-only.
-
-
Notifications
You must be signed in to change notification settings - Fork 164
/
Copy pathfalling-squares.go
executable file
·137 lines (113 loc) · 2.67 KB
/
falling-squares.go
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
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
package problem0699
import "container/heap"
func fallingSquares(positions [][]int) []int {
res := make([]int, 0, len(positions))
pq := make(PQ, 0, len(positions))
for i := 0; i < len(positions); i++ {
sp := &segment{
left: positions[i][0],
right: positions[i][0] + positions[i][1],
height: positions[i][1],
}
height := 0
removes := make([]*segment, 0, len(pq))
// TODO: 添加一个 []*segment 变量,按宽度维护好
// 避免,遍历 pq
//
// l, r := getLeft(ss, sp), getRight(ss, sp)
// for j := l; j <= r; j++ {
// }
for j := 0; j < len(pq); j++ {
if pq[j].right <= sp.left || sp.right <= pq[j].left {
continue
}
height = max(height, pq[j].height)
if sp.left <= pq[j].left && pq[j].right <= sp.right {
removes = append(removes, pq[j])
}
if pq[j].left < sp.left && sp.right < pq[j].right {
heap.Push(&pq, &segment{
left: sp.right,
right: pq[j].right,
height: pq[j].height,
})
pq[j].right = sp.left
break
}
if pq[j].left < sp.left && sp.left < pq[j].right && pq[j].right <= sp.right {
pq[j].right = sp.left
}
if sp.left <= pq[j].left && pq[j].left < sp.right && sp.right < pq[j].right {
pq[j].left = sp.right
}
}
for j := 0; j < len(removes); j++ {
heap.Remove(&pq, removes[j].index)
}
sp.height += height
heap.Push(&pq, sp)
res = append(res, pq[0].height)
}
return res
}
// entry 是 priorityQueue 中的元素
type segment struct {
left, right int
height int
// index 是 entry 在 heap 中的索引号
index int
}
// PQ implements heap.Interface and holds entries.
type PQ []*segment
func (pq PQ) Len() int { return len(pq) }
func (pq PQ) Less(i, j int) bool {
return pq[i].height > pq[j].height
}
func (pq PQ) Swap(i, j int) {
pq[i], pq[j] = pq[j], pq[i]
pq[i].index = i
pq[j].index = j
}
// Push 往 pq 中放 entry
func (pq *PQ) Push(x interface{}) {
temp := x.(*segment)
temp.index = len(*pq)
*pq = append(*pq, temp)
}
// Pop 从 pq 中取出最优先的 entry
func (pq *PQ) Pop() interface{} {
temp := (*pq)[len(*pq)-1]
temp.index = -1 // for safety
*pq = (*pq)[0 : len(*pq)-1]
return temp
}
// func getLeft(ss []*segment, s *segment) int {
// lo, hi := 0, len(ss)-1
// for lo < hi {
// mid := lo + (hi-lo)/2
// if ss[mid].right <= s.left {
// lo = mid + 1
// } else {
// hi = mid - 1
// }
// }
// return lo
// }
// func getRight(ss []*segment, s *segment) int {
// lo, hi := 0, len(ss)-1
// for lo < hi {
// mid := lo + (hi-lo)/2
// if s.right <= ss[mid].left {
// hi = mid - 1
// } else {
// lo = mid + 1
// }
// }
// return hi
// }
func max(a, b int) int {
if a > b {
return a
}
return b
}