Skip to content

Commit b218c09

Browse files
authored
feat: add solutions to lc problem: No.2031 (doocs#2130)
No.2031.Count Subarrays With More Ones Than Zeros
1 parent be10b43 commit b218c09

File tree

7 files changed

+374
-330
lines changed

7 files changed

+374
-330
lines changed

solution/2000-2099/2031.Count Subarrays With More Ones Than Zeros/README.md

+128-113
Original file line numberDiff line numberDiff line change
@@ -53,14 +53,17 @@
5353

5454
<!-- 这里可写通用的实现逻辑 -->
5555

56-
**方法一:树状数组**
56+
**方法一:前缀和 + 树状数组**
5757

58-
树状数组,也称作“二叉索引树”(Binary Indexed Tree)或 Fenwick 树。 它可以高效地实现如下两个操作:
58+
题目需要我们统计所有子数组中 $1$ 的数量大于 $0$ 的数量的子数组的个数,如果我们将数组中的元素 $0$ 看作 $-1$,那么题目就变成了统计所有子数组中元素和大于 $0$ 的子数组的个数。
5959

60-
1. **单点更新** `update(x, delta)`: 把序列 x 位置的数加上一个值 delta;
61-
1. **前缀和查询** `query(x)`:查询序列 `[1,...x]` 区间的区间和,即位置 x 的前缀和。
60+
求子数组的元素和,可以使用前缀和来实现。为了统计所有子数组中元素和大于 $0$ 的子数组的个数,我们可以用树状数组维护每个前缀和出现的次数。初始时前缀和为 $0$ 的次数为 $1$。
6261

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$ 的长度。
6467

6568
<!-- tabs:start -->
6669

@@ -70,43 +73,38 @@
7073

7174
```python
7275
class BinaryIndexedTree:
73-
def __init__(self, n):
74-
n += int(1e5 + 1)
76+
__slots__ = ["n", "c"]
77+
78+
def __init__(self, n: int):
7579
self.n = n
7680
self.c = [0] * (n + 1)
7781

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):
8583
while x <= self.n:
86-
self.c[x] += delta
87-
x += BinaryIndexedTree.lowbit(x)
84+
self.c[x] += v
85+
x += x & -x
8886

89-
def query(self, x):
90-
x += int(1e5 + 1)
87+
def query(self, x: int) -> int:
9188
s = 0
92-
while x > 0:
89+
while x:
9390
s += self.c[x]
94-
x -= BinaryIndexedTree.lowbit(x)
91+
x -= x & -x
9592
return s
9693

9794

9895
class Solution:
9996
def subarraysWithMoreZerosThanOnes(self, nums: List[int]) -> int:
10097
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)
110108
return ans
111109
```
112110

@@ -120,49 +118,38 @@ class BinaryIndexedTree {
120118
private int[] c;
121119

122120
public BinaryIndexedTree(int n) {
123-
n += (int) 1e5 + 1;
124121
this.n = n;
125122
c = new int[n + 1];
126123
}
127124

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;
133128
}
134129
}
135130

136131
public int query(int x) {
137-
x += (int) 1e5 + 1;
138132
int s = 0;
139-
while (x > 0) {
133+
for (; x > 0; x -= x & -x) {
140134
s += c[x];
141-
x -= lowbit(x);
142135
}
143136
return s;
144137
}
145-
146-
public static int lowbit(int x) {
147-
x += (int) 1e5 + 1;
148-
return x & -x;
149-
}
150138
}
151139

152140
class Solution {
153-
private static final int MOD = (int) 1e9 + 7;
154-
155141
public int subarraysWithMoreZerosThanOnes(int[] nums) {
156142
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);
166153
}
167154
return ans;
168155
}
@@ -173,50 +160,44 @@ class Solution {
173160

174161
```cpp
175162
class BinaryIndexedTree {
176-
public:
163+
private:
177164
int n;
178165
vector<int> c;
179166

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) {}
183171

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;
189175
}
190176
}
191177

192178
int query(int x) {
193-
x += 1e5 + 1;
194179
int s = 0;
195-
while (x > 0) {
180+
for (; x > 0; x -= x & -x) {
196181
s += c[x];
197-
x -= lowbit(x);
198182
}
199183
return s;
200184
}
201-
202-
int lowbit(int x) {
203-
x += 1e5 + 1;
204-
return x & -x;
205-
}
206185
};
207186

208187
class Solution {
209188
public:
210189
int subarraysWithMoreZerosThanOnes(vector<int>& nums) {
211190
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);
220201
}
221202
return ans;
222203
}
@@ -232,51 +213,85 @@ type BinaryIndexedTree struct {
232213
}
233214
234215
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)}
243217
}
244218
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
250222
}
251223
}
252224
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]
259228
}
260-
return s
229+
return
261230
}
262231
263-
func subarraysWithMoreZerosThanOnes(nums []int) int {
232+
func subarraysWithMoreZerosThanOnes(nums []int) (ans int) {
264233
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++
269244
}
270-
s[i+1] = s[i] + v
245+
ans += tree.query(s - 1 + base)
246+
ans %= mod
247+
tree.update(s+base, 1)
271248
}
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;
280295
}
281296
```
282297

0 commit comments

Comments
 (0)