53
53
54
54
<!-- 这里可写通用的实现逻辑 -->
55
55
56
- ** 方法一:树状数组**
56
+ ** 方法一:前缀和 + 树状数组**
57
57
58
- 树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
58
+ 题目需要我们统计所有子数组中 $1$ 的数量大于 $0$ 的数量的子数组的个数,如果我们将数组中的元素 $0$ 看作 $-1$,那么题目就变成了统计所有子数组中元素和大于 $0$ 的子数组的个数。
59
59
60
- 1 . ** 单点更新** ` update(x, delta) ` : 把序列 x 位置的数加上一个值 delta;
61
- 1 . ** 前缀和查询** ` query(x) ` :查询序列 ` [1,...x] ` 区间的区间和,即位置 x 的前缀和。
60
+ 求子数组的元素和,可以使用前缀和来实现。为了统计所有子数组中元素和大于 $0$ 的子数组的个数,我们可以用树状数组维护每个前缀和出现的次数。初始时前缀和为 $0$ 的次数为 $1$。
62
61
63
- 这两个操作的时间复杂度均为 $O(\log n)$。
62
+ 接下来,我们遍历数组 $nums$,用变量 $s$ 记录当前的前缀和,用变量 $ans$ 记录答案。对于每个位置 $i$,更新前缀和 $s$,然后我们在树状数组中查询 $[ 0, s)$ 范围内的前缀和出现的次数,将其加到 $ans$ 中,然后在树状数组中更新 $s$ 出现的次数。
63
+
64
+ 最后返回 $ans$ 即可。
65
+
66
+ 时间复杂度 $O(n \times \log n)$,空间复杂度 $O(n)$。其中 $n$ 是数组 $nums$ 的长度。
64
67
65
68
<!-- tabs:start -->
66
69
70
73
71
74
``` python
72
75
class BinaryIndexedTree :
73
- def __init__ (self , n ):
74
- n += int (1e5 + 1 )
76
+ __slots__ = [" n" , " c" ]
77
+
78
+ def __init__ (self , n : int ):
75
79
self .n = n
76
80
self .c = [0 ] * (n + 1 )
77
81
78
- @ staticmethod
79
- def lowbit (x ):
80
- x += int (1e5 + 1 )
81
- return x & - x
82
-
83
- def update (self , x , delta ):
84
- x += int (1e5 + 1 )
82
+ def update (self , x : int , v : int ):
85
83
while x <= self .n:
86
- self .c[x] += delta
87
- x += BinaryIndexedTree.lowbit(x)
84
+ self .c[x] += v
85
+ x += x & - x
88
86
89
- def query (self , x ):
90
- x += int (1e5 + 1 )
87
+ def query (self , x : int ) -> int :
91
88
s = 0
92
- while x > 0 :
89
+ while x:
93
90
s += self .c[x]
94
- x -= BinaryIndexedTree.lowbit(x)
91
+ x -= x & - x
95
92
return s
96
93
97
94
98
95
class Solution :
99
96
def subarraysWithMoreZerosThanOnes (self , nums : List[int ]) -> int :
100
97
n = len (nums)
101
- s = [0 ]
102
- for v in nums:
103
- s.append(s[- 1 ] + (v or - 1 ))
104
- tree = BinaryIndexedTree(n + 1 )
105
- MOD = int (1e9 + 7 )
106
- ans = 0
107
- for v in s:
108
- ans = (ans + tree.query(v - 1 )) % MOD
109
- tree.update(v, 1 )
98
+ base = n + 1
99
+ tree = BinaryIndexedTree(n + base)
100
+ tree.update(base, 1 )
101
+ mod = 10 ** 9 + 7
102
+ ans = s = 0
103
+ for x in nums:
104
+ s += 1 if x else - 1
105
+ ans += tree.query(s - 1 + base)
106
+ ans %= mod
107
+ tree.update(s + base, 1 )
110
108
return ans
111
109
```
112
110
@@ -120,49 +118,38 @@ class BinaryIndexedTree {
120
118
private int [] c;
121
119
122
120
public BinaryIndexedTree (int n ) {
123
- n += (int ) 1e5 + 1 ;
124
121
this . n = n;
125
122
c = new int [n + 1 ];
126
123
}
127
124
128
- public void update (int x , int delta ) {
129
- x += (int ) 1e5 + 1 ;
130
- while (x <= n) {
131
- c[x] += delta;
132
- x += lowbit(x);
125
+ public void update (int x , int v ) {
126
+ for (; x <= n; x += x & - x) {
127
+ c[x] += v;
133
128
}
134
129
}
135
130
136
131
public int query (int x ) {
137
- x += (int ) 1e5 + 1 ;
138
132
int s = 0 ;
139
- while ( x > 0 ) {
133
+ for (; x > 0 ; x -= x & - x ) {
140
134
s += c[x];
141
- x -= lowbit(x);
142
135
}
143
136
return s;
144
137
}
145
-
146
- public static int lowbit (int x ) {
147
- x += (int ) 1e5 + 1 ;
148
- return x & - x;
149
- }
150
138
}
151
139
152
140
class Solution {
153
- private static final int MOD = (int ) 1e9 + 7 ;
154
-
155
141
public int subarraysWithMoreZerosThanOnes (int [] nums ) {
156
142
int n = nums. length;
157
- int [] s = new int [n + 1 ];
158
- for (int i = 0 ; i < n; ++ i) {
159
- s[i + 1 ] = s[i] + (nums[i] == 1 ? 1 : - 1 );
160
- }
161
- BinaryIndexedTree tree = new BinaryIndexedTree (n + 1 );
162
- int ans = 0 ;
163
- for (int v : s) {
164
- ans = (ans + tree. query(v - 1 )) % MOD ;
165
- tree. update(v, 1 );
143
+ int base = n + 1 ;
144
+ BinaryIndexedTree tree = new BinaryIndexedTree (n + base);
145
+ tree. update(base, 1 );
146
+ final int mod = (int ) 1e9 + 7 ;
147
+ int ans = 0 , s = 0 ;
148
+ for (int x : nums) {
149
+ s += x == 0 ? - 1 : 1 ;
150
+ ans += tree. query(s - 1 + base);
151
+ ans %= mod;
152
+ tree. update(s + base, 1 );
166
153
}
167
154
return ans;
168
155
}
@@ -173,50 +160,44 @@ class Solution {
173
160
174
161
``` cpp
175
162
class BinaryIndexedTree {
176
- public :
163
+ private :
177
164
int n;
178
165
vector<int > c;
179
166
180
- BinaryIndexedTree(int _n)
181
- : n(_n + 1e5 + 1)
182
- , c(_n + 1 + 1e5 + 1) {}
167
+ public:
168
+ BinaryIndexedTree(int n)
169
+ : n(n)
170
+ , c(n + 1, 0) {}
183
171
184
- void update (int x, int delta) {
185
- x += 1e5 + 1;
186
- while (x <= n) {
187
- c[ x] += delta;
188
- x += lowbit(x);
172
+ void update(int x, int v) {
173
+ for (; x <= n; x += x & -x) {
174
+ c[x] += v;
189
175
}
190
176
}
191
177
192
178
int query (int x) {
193
- x += 1e5 + 1;
194
179
int s = 0;
195
- while ( x > 0) {
180
+ for (; x > 0; x -= x & -x ) {
196
181
s += c[ x] ;
197
- x -= lowbit(x);
198
182
}
199
183
return s;
200
184
}
201
-
202
- int lowbit(int x) {
203
- x += 1e5 + 1;
204
- return x & -x;
205
- }
206
185
};
207
186
208
187
class Solution {
209
188
public:
210
189
int subarraysWithMoreZerosThanOnes(vector<int >& nums) {
211
190
int n = nums.size();
212
- vector<int > s(n + 1);
213
- for (int i = 0; i < n; ++i) s[ i + 1] = s[ i] + (nums[ i] == 1 ? 1 : -1);
214
- BinaryIndexedTree* tree = new BinaryIndexedTree(n + 1);
215
- int ans = 0;
216
- const int MOD = 1e9 + 7;
217
- for (int v : s) {
218
- ans = (ans + tree->query(v - 1)) % MOD;
219
- tree->update(v, 1);
191
+ int base = n + 1;
192
+ BinaryIndexedTree tree(n + base);
193
+ tree.update(base, 1);
194
+ const int mod = 1e9 + 7;
195
+ int ans = 0, s = 0;
196
+ for (int x : nums) {
197
+ s += (x == 0) ? -1 : 1;
198
+ ans += tree.query(s - 1 + base);
199
+ ans %= mod;
200
+ tree.update(s + base, 1);
220
201
}
221
202
return ans;
222
203
}
@@ -232,51 +213,85 @@ type BinaryIndexedTree struct {
232
213
}
233
214
234
215
func newBinaryIndexedTree(n int) *BinaryIndexedTree {
235
- n += 1e5 + 1
236
- c := make([]int, n+1)
237
- return &BinaryIndexedTree{n, c}
238
- }
239
-
240
- func (this *BinaryIndexedTree) lowbit(x int) int {
241
- x += 1e5 + 1
242
- return x & -x
216
+ return &BinaryIndexedTree{n: n, c: make([]int, n+1)}
243
217
}
244
218
245
- func (this *BinaryIndexedTree) update(x, delta int) {
246
- x += 1e5 + 1
247
- for x <= this.n {
248
- this.c[x] += delta
249
- x += this.lowbit(x)
219
+ func (bit *BinaryIndexedTree) update(x, v int) {
220
+ for ; x <= bit.n; x += x & -x {
221
+ bit.c[x] += v
250
222
}
251
223
}
252
224
253
- func (this *BinaryIndexedTree) query(x int) int {
254
- s := 0
255
- x += 1e5 + 1
256
- for x > 0 {
257
- s += this.c[x]
258
- x -= this.lowbit(x)
225
+ func (bit *BinaryIndexedTree) query(x int) (s int) {
226
+ for ; x > 0; x -= x & -x {
227
+ s += bit.c[x]
259
228
}
260
- return s
229
+ return
261
230
}
262
231
263
- func subarraysWithMoreZerosThanOnes(nums []int) int {
232
+ func subarraysWithMoreZerosThanOnes(nums []int) (ans int) {
264
233
n := len(nums)
265
- s := make([]int, n+1)
266
- for i, v := range nums {
267
- if v == 0 {
268
- v = -1
234
+ base := n + 1
235
+ tree := newBinaryIndexedTree(n + base)
236
+ tree.update(base, 1)
237
+ const mod = int(1e9) + 7
238
+ s := 0
239
+ for _, x := range nums {
240
+ if x == 0 {
241
+ s--
242
+ } else {
243
+ s++
269
244
}
270
- s[i+1] = s[i] + v
245
+ ans += tree.query(s - 1 + base)
246
+ ans %= mod
247
+ tree.update(s+base, 1)
271
248
}
272
- tree := newBinaryIndexedTree(n + 1)
273
- ans := 0
274
- mod := int(1e9 + 7)
275
- for _, v := range s {
276
- ans = (ans + tree.query(v-1)) % mod
277
- tree.update(v, 1)
278
- }
279
- return ans
249
+ return
250
+ }
251
+ ```
252
+
253
+ ### ** TypeScript**
254
+
255
+ ``` ts
256
+ class BinaryIndexedTree {
257
+ private n: number ;
258
+ private c: number [];
259
+
260
+ constructor (n : number ) {
261
+ this .n = n ;
262
+ this .c = Array (n + 1 ).fill (0 );
263
+ }
264
+
265
+ update(x : number , v : number ): void {
266
+ for (; x <= this .n ; x += x & - x ) {
267
+ this .c [x ] += v ;
268
+ }
269
+ }
270
+
271
+ query(x : number ): number {
272
+ let s = 0 ;
273
+ for (; x > 0 ; x -= x & - x ) {
274
+ s += this .c [x ];
275
+ }
276
+ return s ;
277
+ }
278
+ }
279
+
280
+ function subarraysWithMoreZerosThanOnes(nums : number []): number {
281
+ const n: number = nums .length ;
282
+ const base: number = n + 1 ;
283
+ const tree: BinaryIndexedTree = new BinaryIndexedTree (n + base );
284
+ tree .update (base , 1 );
285
+ const mod: number = 1e9 + 7 ;
286
+ let ans: number = 0 ;
287
+ let s: number = 0 ;
288
+ for (const x of nums ) {
289
+ s += x === 0 ? - 1 : 1 ;
290
+ ans += tree .query (s - 1 + base );
291
+ ans %= mod ;
292
+ tree .update (s + base , 1 );
293
+ }
294
+ return ans ;
280
295
}
281
296
```
282
297
0 commit comments