Skip to content

Commit 6fc9ad7

Browse files
authored
feat: add solutions to lc problem: No.0683 (#1800)
1 parent 49df981 commit 6fc9ad7

File tree

7 files changed

+389
-279
lines changed

7 files changed

+389
-279
lines changed

solution/0600-0699/0683.K Empty Slots/README.md

+103-68
Original file line numberDiff line numberDiff line change
@@ -52,12 +52,9 @@ bulbs = [1,3,2],k = 1
5252

5353
**方法一:树状数组**
5454

55-
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
55+
我们可以使用树状数组来维护区间和,每一次打开灯泡,我们就在树状数组中更新对应位置的值,然后查询当前位置左边 $k$ 个灯泡是否都是关闭的,并且第 $k+1$ 个灯泡是否已经打开;或者查询当前位置右边 $k$ 个灯泡是否都是关闭的,并且第 $k+1$ 个灯泡是否已经打开。如果满足这两个条件之一,那么就说明当前位置是一个符合要求的位置,我们就可以返回当前的天数。
5656

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$ 是灯泡的数量。
6158

6259
<!-- tabs:start -->
6360

@@ -71,40 +68,32 @@ class BinaryIndexedTree:
7168
self.n = n
7269
self.c = [0] * (n + 1)
7370

74-
@staticmethod
75-
def lowbit(x):
76-
return x & -x
77-
7871
def update(self, x, delta):
7972
while x <= self.n:
8073
self.c[x] += delta
81-
x += BinaryIndexedTree.lowbit(x)
74+
x += x & -x
8275

8376
def query(self, x):
8477
s = 0
85-
while x > 0:
78+
while x:
8679
s += self.c[x]
87-
x -= BinaryIndexedTree.lowbit(x)
80+
x -= x & -x
8881
return s
8982

9083

9184
class Solution:
9285
def kEmptySlots(self, bulbs: List[int], k: int) -> int:
9386
n = len(bulbs)
9487
tree = BinaryIndexedTree(n)
88+
vis = [False] * (n + 1)
9589
for i, x in enumerate(bulbs, 1):
9690
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:
10897
return i
10998
return -1
11099
```
@@ -118,15 +107,18 @@ class Solution {
118107
public int kEmptySlots(int[] bulbs, int k) {
119108
int n = bulbs.length;
120109
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];
123113
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;
130122
}
131123
}
132124
return -1;
@@ -139,28 +131,22 @@ class BinaryIndexedTree {
139131

140132
public BinaryIndexedTree(int n) {
141133
this.n = n;
142-
c = new int[n + 1];
134+
this.c = new int[n + 1];
143135
}
144136

145137
public void update(int x, int delta) {
146-
while (x <= n) {
138+
for (; x <= n; x += x & -x) {
147139
c[x] += delta;
148-
x += lowbit(x);
149140
}
150141
}
151142

152143
public int query(int x) {
153144
int s = 0;
154-
while (x > 0) {
145+
for (; x > 0; x -= x & -x) {
155146
s += c[x];
156-
x -= lowbit(x);
157147
}
158148
return s;
159149
}
160-
161-
public static int lowbit(int x) {
162-
return x & -x;
163-
}
164150
}
165151
```
166152

@@ -177,37 +163,39 @@ public:
177163
, c(_n + 1) {}
178164

179165
void update(int x, int delta) {
180-
while (x <= n) {
166+
for (; x <= n; x += x & -x) {
181167
c[x] += delta;
182-
x += lowbit(x);
183168
}
184169
}
185170

186171
int query(int x) {
187172
int s = 0;
188-
while (x > 0) {
173+
for (; x; x -= x & -x) {
189174
s += c[x];
190-
x -= lowbit(x);
191175
}
192176
return s;
193177
}
194-
195-
int lowbit(int x) {
196-
return x & -x;
197-
}
198178
};
199179

200180
class Solution {
201181
public:
202182
int kEmptySlots(vector<int>& bulbs, int k) {
203183
int n = bulbs.size();
204184
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];
207189
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+
}
211199
}
212200
return -1;
213201
}
@@ -227,41 +215,88 @@ func newBinaryIndexedTree(n int) *BinaryIndexedTree {
227215
return &BinaryIndexedTree{n, c}
228216
}
229217
230-
func (this *BinaryIndexedTree) lowbit(x int) int {
231-
return x & -x
232-
}
233-
234218
func (this *BinaryIndexedTree) update(x, delta int) {
235-
for x <= this.n {
219+
for ; x <= this.n; x += x & -x {
236220
this.c[x] += delta
237-
x += this.lowbit(x)
238221
}
239222
}
240223
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 {
244226
s += this.c[x]
245-
x -= this.lowbit(x)
246227
}
247-
return s
228+
return
248229
}
249230
250231
func kEmptySlots(bulbs []int, k int) int {
251232
n := len(bulbs)
252233
tree := newBinaryIndexedTree(n)
234+
vis := make([]bool, n+1)
253235
for i, x := range bulbs {
254236
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
259246
}
260247
}
261248
return -1
262249
}
263250
```
264251

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+
265300
### **...**
266301

267302
```

0 commit comments

Comments
 (0)