@@ -52,12 +52,9 @@ bulbs = [1,3,2],k = 1
52
52
53
53
** 方法一:树状数组**
54
54
55
- 树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
55
+ 我们可以使用树状数组来维护区间和,每一次打开灯泡,我们就在树状数组中更新对应位置的值,然后查询当前位置左边 $k$ 个灯泡是否都是关闭的,并且第 $k+1$ 个灯泡是否已经打开;或者查询当前位置右边 $k$ 个灯泡是否都是关闭的,并且第 $k+1$ 个灯泡是否已经打开。如果满足这两个条件之一,那么就说明当前位置是一个符合要求的位置,我们就可以返回当前的天数。
56
56
57
- 1 . ** 单点更新** ` update(x, delta) ` : 把序列 x 位置的数加上一个值 delta;
58
- 1 . ** 前缀和查询** ` query(x) ` :查询序列 ` [1,...x] ` 区间的区间和,即位置 x 的前缀和。
59
-
60
- 这两个操作的时间复杂度均为 $O(\log n)$。
57
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是灯泡的数量。
61
58
62
59
<!-- tabs:start -->
63
60
@@ -71,40 +68,32 @@ class BinaryIndexedTree:
71
68
self .n = n
72
69
self .c = [0 ] * (n + 1 )
73
70
74
- @ staticmethod
75
- def lowbit (x ):
76
- return x & - x
77
-
78
71
def update (self , x , delta ):
79
72
while x <= self .n:
80
73
self .c[x] += delta
81
- x += BinaryIndexedTree.lowbit(x)
74
+ x += x & - x
82
75
83
76
def query (self , x ):
84
77
s = 0
85
- while x > 0 :
78
+ while x:
86
79
s += self .c[x]
87
- x -= BinaryIndexedTree.lowbit(x)
80
+ x -= x & - x
88
81
return s
89
82
90
83
91
84
class Solution :
92
85
def kEmptySlots (self , bulbs : List[int ], k : int ) -> int :
93
86
n = len (bulbs)
94
87
tree = BinaryIndexedTree(n)
88
+ vis = [False ] * (n + 1 )
95
89
for i, x in enumerate (bulbs, 1 ):
96
90
tree.update(x, 1 )
97
- case1 = (
98
- x - k - 1 > 0
99
- and tree.query(x - k - 1 ) - tree.query(x - k - 2 ) == 1
100
- and tree.query(x - 1 ) - tree.query(x - k - 1 ) == 0
101
- )
102
- case2 = (
103
- x + k + 1 <= n
104
- and tree.query(x + k + 1 ) - tree.query(x + k) == 1
105
- and tree.query(x + k) - tree.query(x) == 0
106
- )
107
- if case1 or case2:
91
+ vis[x] = True
92
+ y = x - k - 1
93
+ if y > 0 and vis[y] and tree.query(x - 1 ) - tree.query(y) == 0 :
94
+ return i
95
+ y = x + k + 1
96
+ if y <= n and vis[y] and tree.query(y - 1 ) - tree.query(x) == 0 :
108
97
return i
109
98
return - 1
110
99
```
@@ -118,15 +107,18 @@ class Solution {
118
107
public int kEmptySlots (int [] bulbs , int k ) {
119
108
int n = bulbs. length;
120
109
BinaryIndexedTree tree = new BinaryIndexedTree (n);
121
- for (int i = 0 ; i < n; ++ i) {
122
- int x = bulbs[i];
110
+ boolean [] vis = new boolean [n + 1 ];
111
+ for (int i = 1 ; i <= n; ++ i) {
112
+ int x = bulbs[i - 1 ];
123
113
tree. update(x, 1 );
124
- boolean case1 = x - k - 1 > 0 && tree. query(x - k - 1 ) - tree. query(x - k - 2 ) == 1
125
- && tree. query(x - 1 ) - tree. query(x - k - 1 ) == 0 ;
126
- boolean case2 = x + k + 1 <= n && tree. query(x + k + 1 ) - tree. query(x + k) == 1
127
- && tree. query(x + k) - tree. query(x) == 0 ;
128
- if (case1 || case2) {
129
- return i + 1 ;
114
+ vis[x] = true ;
115
+ int y = x - k - 1 ;
116
+ if (y > 0 && vis[y] && tree. query(x - 1 ) - tree. query(y) == 0 ) {
117
+ return i;
118
+ }
119
+ y = x + k + 1 ;
120
+ if (y <= n && vis[y] && tree. query(y - 1 ) - tree. query(x) == 0 ) {
121
+ return i;
130
122
}
131
123
}
132
124
return - 1 ;
@@ -139,28 +131,22 @@ class BinaryIndexedTree {
139
131
140
132
public BinaryIndexedTree (int n ) {
141
133
this . n = n;
142
- c = new int [n + 1 ];
134
+ this . c = new int [n + 1 ];
143
135
}
144
136
145
137
public void update (int x , int delta ) {
146
- while ( x <= n) {
138
+ for (; x <= n; x += x & - x ) {
147
139
c[x] += delta;
148
- x += lowbit(x);
149
140
}
150
141
}
151
142
152
143
public int query (int x ) {
153
144
int s = 0 ;
154
- while ( x > 0 ) {
145
+ for (; x > 0 ; x -= x & - x ) {
155
146
s += c[x];
156
- x -= lowbit(x);
157
147
}
158
148
return s;
159
149
}
160
-
161
- public static int lowbit (int x ) {
162
- return x & - x;
163
- }
164
150
}
165
151
```
166
152
@@ -177,37 +163,39 @@ public:
177
163
, c(_n + 1) {}
178
164
179
165
void update (int x, int delta) {
180
- while ( x <= n) {
166
+ for (; x <= n; x += x & -x ) {
181
167
c[ x] += delta;
182
- x += lowbit(x);
183
168
}
184
169
}
185
170
186
171
int query(int x) {
187
172
int s = 0;
188
- while (x > 0 ) {
173
+ for (; x; x -= x & -x ) {
189
174
s += c[x];
190
- x -= lowbit(x);
191
175
}
192
176
return s;
193
177
}
194
-
195
- int lowbit(int x) {
196
- return x & -x;
197
- }
198
178
};
199
179
200
180
class Solution {
201
181
public:
202
182
int kEmptySlots(vector<int >& bulbs, int k) {
203
183
int n = bulbs.size();
204
184
BinaryIndexedTree* tree = new BinaryIndexedTree(n);
205
- for (int i = 0; i < n; ++i) {
206
- int x = bulbs[ i] ;
185
+ bool vis[ n + 1] ;
186
+ memset(vis, false, sizeof(vis));
187
+ for (int i = 1; i <= n; ++i) {
188
+ int x = bulbs[ i - 1] ;
207
189
tree->update(x, 1);
208
- bool case1 = x - k - 1 > 0 && tree->query(x - k - 1) - tree->query(x - k - 2) == 1 && tree->query(x - 1) - tree->query(x - k - 1) == 0;
209
- bool case2 = x + k + 1 <= n && tree->query(x + k + 1) - tree->query(x + k) == 1 && tree->query(x + k) - tree->query(x) == 0;
210
- if (case1 || case2) return i + 1;
190
+ vis[ x] = true;
191
+ int y = x - k - 1;
192
+ if (y > 0 && vis[ y] && tree->query(x - 1) - tree->query(y) == 0) {
193
+ return i;
194
+ }
195
+ y = x + k + 1;
196
+ if (y <= n && vis[ y] && tree->query(y - 1) - tree->query(x) == 0) {
197
+ return i;
198
+ }
211
199
}
212
200
return -1;
213
201
}
@@ -227,41 +215,88 @@ func newBinaryIndexedTree(n int) *BinaryIndexedTree {
227
215
return &BinaryIndexedTree{n, c}
228
216
}
229
217
230
- func (this *BinaryIndexedTree) lowbit(x int) int {
231
- return x & -x
232
- }
233
-
234
218
func (this *BinaryIndexedTree) update(x, delta int) {
235
- for x <= this.n {
219
+ for ; x <= this.n; x += x & -x {
236
220
this.c[x] += delta
237
- x += this.lowbit(x)
238
221
}
239
222
}
240
223
241
- func (this *BinaryIndexedTree) query(x int) int {
242
- s := 0
243
- for x > 0 {
224
+ func (this *BinaryIndexedTree) query(x int) (s int) {
225
+ for ; x > 0; x -= x & -x {
244
226
s += this.c[x]
245
- x -= this.lowbit(x)
246
227
}
247
- return s
228
+ return
248
229
}
249
230
250
231
func kEmptySlots(bulbs []int, k int) int {
251
232
n := len(bulbs)
252
233
tree := newBinaryIndexedTree(n)
234
+ vis := make([]bool, n+1)
253
235
for i, x := range bulbs {
254
236
tree.update(x, 1)
255
- case1 := x-k-1 > 0 && tree.query(x-k-1)-tree.query(x-k-2) == 1 && tree.query(x-1)-tree.query(x-k-1) == 0
256
- case2 := x+k+1 <= n && tree.query(x+k+1)-tree.query(x+k) == 1 && tree.query(x+k)-tree.query(x) == 0
257
- if case1 || case2 {
258
- return i + 1
237
+ vis[x] = true
238
+ i++
239
+ y := x - k - 1
240
+ if y > 0 && vis[y] && tree.query(x-1)-tree.query(y) == 0 {
241
+ return i
242
+ }
243
+ y = x + k + 1
244
+ if y <= n && vis[y] && tree.query(y-1)-tree.query(x) == 0 {
245
+ return i
259
246
}
260
247
}
261
248
return -1
262
249
}
263
250
```
264
251
252
+ ### ** TypeScript**
253
+
254
+ ``` ts
255
+ class BinaryIndexedTree {
256
+ private n: number ;
257
+ private c: number [];
258
+
259
+ constructor (n : number ) {
260
+ this .n = n ;
261
+ this .c = Array (n + 1 ).fill (0 );
262
+ }
263
+
264
+ public update(x : number , delta : number ) {
265
+ for (; x <= this .n ; x += x & - x ) {
266
+ this .c [x ] += delta ;
267
+ }
268
+ }
269
+
270
+ public query(x : number ): number {
271
+ let s = 0 ;
272
+ for (; x > 0 ; x -= x & - x ) {
273
+ s += this .c [x ];
274
+ }
275
+ return s ;
276
+ }
277
+ }
278
+
279
+ function kEmptySlots(bulbs : number [], k : number ): number {
280
+ const n = bulbs .length ;
281
+ const tree = new BinaryIndexedTree (n );
282
+ const vis: boolean [] = Array (n + 1 ).fill (false );
283
+ for (let i = 1 ; i <= n ; ++ i ) {
284
+ const x = bulbs [i - 1 ];
285
+ tree .update (x , 1 );
286
+ vis [x ] = true ;
287
+ let y = x - k - 1 ;
288
+ if (y > 0 && vis [y ] && tree .query (x - 1 ) - tree .query (y ) === 0 ) {
289
+ return i ;
290
+ }
291
+ y = x + k + 1 ;
292
+ if (y <= n && vis [y ] && tree .query (y - 1 ) - tree .query (x ) === 0 ) {
293
+ return i ;
294
+ }
295
+ }
296
+ return - 1 ;
297
+ }
298
+ ```
299
+
265
300
### ** ...**
266
301
267
302
```
0 commit comments