58
58
59
59
<!-- 这里可写通用的实现逻辑 -->
60
60
61
- 优先队列。
61
+ ** 方法一:贪心 + 优先队列(小根堆)**
62
+
63
+ 我们可以使用贪心的思路,每次选择最短的两根棍子进行拼接,这样可以保证拼接的代价最小。
64
+
65
+ 因此,我们可以使用优先队列(小根堆)来维护当前棍子的长度,每次从优先队列中取出两根棍子进行拼接,再将拼接后的棍子放回优先队列中,直到优先队列中只剩下一根棍子为止。
66
+
67
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 ` sticks ` 的长度。
62
68
63
69
<!-- tabs:start -->
64
70
69
75
``` python
70
76
class Solution :
71
77
def connectSticks (self , sticks : List[int ]) -> int :
72
- h = []
73
- for s in sticks:
74
- heappush(h, s)
75
- res = 0
76
- while len (h) > 1 :
77
- val = heappop(h) + heappop(h)
78
- res += val
79
- heappush(h, val)
80
- return res
78
+ heapify(sticks)
79
+ ans = 0
80
+ while len (sticks) > 1 :
81
+ z = heappop(sticks) + heappop(sticks)
82
+ ans += z
83
+ heappush(sticks, z)
84
+ return ans
81
85
```
82
86
83
87
### ** Java**
@@ -88,16 +92,16 @@ class Solution:
88
92
class Solution {
89
93
public int connectSticks (int [] sticks ) {
90
94
PriorityQueue<Integer > pq = new PriorityQueue<> ();
91
- for (int s : sticks) {
92
- pq. offer(s );
95
+ for (int x : sticks) {
96
+ pq. offer(x );
93
97
}
94
- int res = 0 ;
98
+ int ans = 0 ;
95
99
while (pq. size() > 1 ) {
96
- int val = pq. poll() + pq. poll();
97
- res += val ;
98
- pq. offer(val );
100
+ int z = pq. poll() + pq. poll();
101
+ ans += z ;
102
+ pq. offer(z );
99
103
}
100
- return res ;
104
+ return ans ;
101
105
}
102
106
}
103
107
```
@@ -109,51 +113,130 @@ class Solution {
109
113
public:
110
114
int connectSticks(vector<int >& sticks) {
111
115
priority_queue<int, vector<int >, greater<int >> pq;
112
- for (int x : sticks) pq.push(x);
113
- int res = 0;
116
+ for (auto& x : sticks) {
117
+ pq.push(x);
118
+ }
119
+ int ans = 0;
114
120
while (pq.size() > 1) {
115
- int val = pq.top();
121
+ int x = pq.top();
116
122
pq.pop();
117
- val + = pq.top();
123
+ int y = pq.top();
118
124
pq.pop();
119
- res += val;
120
- pq.push(val);
125
+ int z = x + y;
126
+ ans += z;
127
+ pq.push(z);
121
128
}
122
- return res ;
129
+ return ans ;
123
130
}
124
131
};
125
132
```
126
133
127
134
### **Go**
128
135
129
136
```go
130
- func connectSticks(sticks []int) int {
131
- h := IntHeap(sticks)
132
- heap.Init(&h)
133
- res := 0
134
- for h.Len() > 1 {
135
- val := heap.Pop(&h).(int)
136
- val += heap.Pop(&h).(int)
137
- res += val
138
- heap.Push(&h, val)
137
+ func connectSticks(sticks []int) (ans int) {
138
+ hp := &hp{sticks}
139
+ heap.Init(hp)
140
+ for hp.Len() > 1 {
141
+ x, y := heap.Pop(hp).(int), heap.Pop(hp).(int)
142
+ ans += x + y
143
+ heap.Push(hp, x+y)
139
144
}
140
- return res
145
+ return
141
146
}
142
147
143
- type IntHeap []int
148
+ type hp struct{ sort.IntSlice }
144
149
145
- func (h IntHeap) Len() int { return len(h) }
146
- func (h IntHeap) Less(i, j int) bool { return h[i] < h[j] }
147
- func (h IntHeap) Swap(i, j int) { h[i], h[j] = h[j], h[i] }
148
- func (h *IntHeap) Push(x interface{}) {
149
- *h = append(*h, x.(int))
150
+ func (h hp) Less(i, j int) bool { return h.IntSlice[i] < h.IntSlice[j] }
151
+ func (h *hp) Push(v interface{}) { h.IntSlice = append(h.IntSlice, v.(int)) }
152
+ func (h *hp) Pop() interface{} {
153
+ a := h.IntSlice
154
+ v := a[len(a)-1]
155
+ h.IntSlice = a[:len(a)-1]
156
+ return v
150
157
}
151
- func (h *IntHeap) Pop() interface{} {
152
- old := *h
153
- n := len(old)
154
- x := old[n-1]
155
- *h = old[0 : n-1]
156
- return x
158
+ ```
159
+
160
+ ### ** TypeScript**
161
+
162
+ ``` ts
163
+ function connectSticks(sticks : number []): number {
164
+ const pq = new Heap (sticks );
165
+ let ans = 0 ;
166
+ while (pq .size () > 1 ) {
167
+ const x = pq .pop ();
168
+ const y = pq .pop ();
169
+ ans += x + y ;
170
+ pq .push (x + y );
171
+ }
172
+ return ans ;
173
+ }
174
+
175
+ type Compare <T > = (lhs : T , rhs : T ) => number ;
176
+
177
+ class Heap <T = number > {
178
+ data: Array <T | null >;
179
+ lt: (i : number , j : number ) => boolean ;
180
+ constructor ();
181
+ constructor (data : T []);
182
+ constructor (compare : Compare <T >);
183
+ constructor (data : T [], compare : Compare <T >);
184
+ constructor (data : T [] | Compare <T >, compare ? : (lhs : T , rhs : T ) => number );
185
+ constructor (
186
+ data : T [] | Compare <T > = [],
187
+ compare : Compare <T > = (lhs : T , rhs : T ) =>
188
+ lhs < rhs ? - 1 : lhs > rhs ? 1 : 0 ,
189
+ ) {
190
+ if (typeof data === ' function' ) {
191
+ compare = data ;
192
+ data = [];
193
+ }
194
+ this .data = [null , ... data ];
195
+ this .lt = (i , j ) => compare (this .data [i ]! , this .data [j ]! ) < 0 ;
196
+ for (let i = this .size (); i > 0 ; i -- ) this .heapify (i );
197
+ }
198
+
199
+ size(): number {
200
+ return this .data .length - 1 ;
201
+ }
202
+
203
+ push(v : T ): void {
204
+ this .data .push (v );
205
+ let i = this .size ();
206
+ while (i >> 1 !== 0 && this .lt (i , i >> 1 )) this .swap (i , (i >>= 1 ));
207
+ }
208
+
209
+ pop(): T {
210
+ this .swap (1 , this .size ());
211
+ const top = this .data .pop ();
212
+ this .heapify (1 );
213
+ return top ! ;
214
+ }
215
+
216
+ top(): T {
217
+ return this .data [1 ]! ;
218
+ }
219
+ heapify(i : number ): void {
220
+ while (true ) {
221
+ let min = i ;
222
+ const [l, r, n] = [i * 2 , i * 2 + 1 , this .data .length ];
223
+ if (l < n && this .lt (l , min )) min = l ;
224
+ if (r < n && this .lt (r , min )) min = r ;
225
+ if (min !== i ) {
226
+ this .swap (i , min );
227
+ i = min ;
228
+ } else break ;
229
+ }
230
+ }
231
+
232
+ clear(): void {
233
+ this .data = [null ];
234
+ }
235
+
236
+ private swap(i : number , j : number ): void {
237
+ const d = this .data ;
238
+ [d [i ], d [j ]] = [d [j ], d [i ]];
239
+ }
157
240
}
158
241
```
159
242
0 commit comments