Skip to content

Commit 547bd21

Browse files
committed
feat: add solutions to lc problem: No.3209
No.3209.Number of Subarrays With AND Value of K
1 parent 6f425ec commit 547bd21

File tree

7 files changed

+252
-8
lines changed

7 files changed

+252
-8
lines changed

solution/3200-3299/3209.Number of Subarrays With AND Value of K/README.md

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -69,32 +69,117 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3209.Nu
6969

7070
<!-- solution:start -->
7171

72-
### 方法一
72+
### 方法一:哈希表 + 枚举
73+
74+
根据题目描述,我们需要求出数组 $\textit{nums}$ 下标 $l$ 到 $r$ 的元素的按位与运算的结果,即 $\textit{nums}[l] \land \textit{nums}[l + 1] \land \cdots \land \textit{nums}[r]$。其中 $\land$ 表示按位与运算。
75+
76+
如果我们每次固定右端点 $r$,那么左端点 $l$ 的范围是 $[0, r]$。由于按位与之和随着 $l$ 的减小而单调递减,并且 $nums[i]$ 的值不超过 $10^9$,因此区间 $[0, r]$ 最多只有 $30$ 种不同的值。因此,我们可以用一个集合来维护所有的 $\textit{nums}[l] \land \textit{nums}[l + 1] \land \cdots \land \textit{nums}[r]$ 的值,以及这些值出现的次数。
77+
78+
当我们从 $r$ 遍历到 $r+1$ 时,以 $r+1$ 为右端点的值,就是集合中每个值与 $nums[r + 1]$ 进行按位与运算得到的值,再加上 $\textit{nums}[r + 1]$ 本身。
79+
80+
因此,我们只需要枚举集合中的每个值,与 $\textit{nums[r]}$ 进行按位与运算,就可以得到以 $r$ 为右端点的所有值及其出现的次数。然后,我们还需要将 $\textit{nums[r]}$ 的出现次数加上去。此时,我们将值为 $k$ 的出现次数累加到答案中。继续遍历 $r$,直到遍历完整个数组。
81+
82+
时间复杂度 $O(n \times \log M)$,空间复杂度 $O(\log M)$。其中 $n$ 和 $M$ 分别是数组 $\textit{nums}$ 的长度和数组 $\textit{nums}$ 中元素的最大值。
7383

7484
<!-- tabs:start -->
7585

7686
#### Python3
7787

7888
```python
79-
89+
class Solution:
90+
def countSubarrays(self, nums: List[int], k: int) -> int:
91+
ans = 0
92+
pre = Counter()
93+
for x in nums:
94+
cur = Counter()
95+
for y, v in pre.items():
96+
cur[x & y] += v
97+
cur[x] += 1
98+
ans += cur[k]
99+
pre = cur
100+
return ans
80101
```
81102

82103
#### Java
83104

84105
```java
85-
106+
class Solution {
107+
public long countSubarrays(int[] nums, int k) {
108+
long ans = 0;
109+
Map<Integer, Integer> pre = new HashMap<>();
110+
for (int x : nums) {
111+
Map<Integer, Integer> cur = new HashMap<>();
112+
for (var e : pre.entrySet()) {
113+
int y = e.getKey(), v = e.getValue();
114+
cur.merge(x & y, v, Integer::sum);
115+
}
116+
cur.merge(x, 1, Integer::sum);
117+
ans += cur.getOrDefault(k, 0);
118+
pre = cur;
119+
}
120+
return ans;
121+
}
122+
}
86123
```
87124

88125
#### C++
89126

90127
```cpp
91-
128+
class Solution {
129+
public:
130+
long long countSubarrays(vector<int>& nums, int k) {
131+
long long ans = 0;
132+
unordered_map<int, int> pre;
133+
for (int x : nums) {
134+
unordered_map<int, int> cur;
135+
for (auto& [y, v] : pre) {
136+
cur[x & y] += v;
137+
}
138+
cur[x]++;
139+
ans += cur[k];
140+
pre = cur;
141+
}
142+
return ans;
143+
}
144+
};
92145
```
93146
94147
#### Go
95148
96149
```go
150+
func countSubarrays(nums []int, k int) (ans int64) {
151+
pre := map[int]int{}
152+
for _, x := range nums {
153+
cur := map[int]int{}
154+
for y, v := range pre {
155+
cur[x&y] += v
156+
}
157+
cur[x]++
158+
ans += int64(cur[k])
159+
pre = cur
160+
}
161+
return
162+
}
163+
```
97164

165+
#### TypeScript
166+
167+
```ts
168+
function countSubarrays(nums: number[], k: number): number {
169+
let ans = 0;
170+
let pre = new Map<number, number>();
171+
for (const x of nums) {
172+
const cur = new Map<number, number>();
173+
for (const [y, v] of pre) {
174+
const z = x & y;
175+
cur.set(z, (cur.get(z) || 0) + v);
176+
}
177+
cur.set(x, (cur.get(x) || 0) + 1);
178+
ans += cur.get(k) || 0;
179+
pre = cur;
180+
}
181+
return ans;
182+
}
98183
```
99184

100185
<!-- tabs:end -->

solution/3200-3299/3209.Number of Subarrays With AND Value of K/README_EN.md

Lines changed: 89 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -67,32 +67,117 @@ edit_url: https://github.com/doocs/leetcode/edit/main/solution/3200-3299/3209.Nu
6767

6868
<!-- solution:start -->
6969

70-
### Solution 1
70+
### Solution 1: Hash Table + Enumeration
71+
72+
According to the problem description, we need to find the result of the bitwise AND operation of elements from index $l$ to $r$ in the array $\textit{nums}$, that is, $\textit{nums}[l] \land \textit{nums}[l + 1] \land \cdots \land \textit{nums}[r]$, where $\land$ represents the bitwise AND operation.
73+
74+
If we fix the right endpoint $r$, then the range of the left endpoint $l$ is $[0, r]$. Since the sum of bitwise AND decreases monotonically as $l$ decreases, and the value of $nums[i]$ does not exceed $10^9$, the interval $[0, r]$ can have at most $30$ different values. Therefore, we can use a set to maintain all the values of $\textit{nums}[l] \land \textit{nums}[l + 1] \land \cdots \land \textit{nums}[r]$ and the number of times these values occur.
75+
76+
When we traverse from $r$ to $r+1$, the values with $r+1$ as the right endpoint are the values obtained by performing the bitwise AND operation of each value in the set with $nums[r + 1]$, plus $\textit{nums}[r + 1]$ itself.
77+
78+
Therefore, we only need to enumerate each value in the set and perform the bitwise AND operation with $\textit{nums[r]}$ to get all the values and their occurrences with $r$ as the right endpoint. Then, we need to add the occurrence count of $\textit{nums[r]}$. At this point, we add the occurrence count of value $k$ to the answer. Continue traversing $r$ until the entire array is traversed.
79+
80+
The time complexity is $O(n \times \log M)$, and the space complexity is $O(\log M)$. Here, $n$ and $M$ are the length of the array $\textit{nums}$ and the maximum value in the array $\textit{nums}$, respectively.
7181

7282
<!-- tabs:start -->
7383

7484
#### Python3
7585

7686
```python
77-
87+
class Solution:
88+
def countSubarrays(self, nums: List[int], k: int) -> int:
89+
ans = 0
90+
pre = Counter()
91+
for x in nums:
92+
cur = Counter()
93+
for y, v in pre.items():
94+
cur[x & y] += v
95+
cur[x] += 1
96+
ans += cur[k]
97+
pre = cur
98+
return ans
7899
```
79100

80101
#### Java
81102

82103
```java
83-
104+
class Solution {
105+
public long countSubarrays(int[] nums, int k) {
106+
long ans = 0;
107+
Map<Integer, Integer> pre = new HashMap<>();
108+
for (int x : nums) {
109+
Map<Integer, Integer> cur = new HashMap<>();
110+
for (var e : pre.entrySet()) {
111+
int y = e.getKey(), v = e.getValue();
112+
cur.merge(x & y, v, Integer::sum);
113+
}
114+
cur.merge(x, 1, Integer::sum);
115+
ans += cur.getOrDefault(k, 0);
116+
pre = cur;
117+
}
118+
return ans;
119+
}
120+
}
84121
```
85122

86123
#### C++
87124

88125
```cpp
89-
126+
class Solution {
127+
public:
128+
long long countSubarrays(vector<int>& nums, int k) {
129+
long long ans = 0;
130+
unordered_map<int, int> pre;
131+
for (int x : nums) {
132+
unordered_map<int, int> cur;
133+
for (auto& [y, v] : pre) {
134+
cur[x & y] += v;
135+
}
136+
cur[x]++;
137+
ans += cur[k];
138+
pre = cur;
139+
}
140+
return ans;
141+
}
142+
};
90143
```
91144
92145
#### Go
93146
94147
```go
148+
func countSubarrays(nums []int, k int) (ans int64) {
149+
pre := map[int]int{}
150+
for _, x := range nums {
151+
cur := map[int]int{}
152+
for y, v := range pre {
153+
cur[x&y] += v
154+
}
155+
cur[x]++
156+
ans += int64(cur[k])
157+
pre = cur
158+
}
159+
return
160+
}
161+
```
95162

163+
#### TypeScript
164+
165+
```ts
166+
function countSubarrays(nums: number[], k: number): number {
167+
let ans = 0;
168+
let pre = new Map<number, number>();
169+
for (const x of nums) {
170+
const cur = new Map<number, number>();
171+
for (const [y, v] of pre) {
172+
const z = x & y;
173+
cur.set(z, (cur.get(z) || 0) + v);
174+
}
175+
cur.set(x, (cur.get(x) || 0) + 1);
176+
ans += cur.get(k) || 0;
177+
pre = cur;
178+
}
179+
return ans;
180+
}
96181
```
97182

98183
<!-- tabs:end -->
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution {
2+
public:
3+
long long countSubarrays(vector<int>& nums, int k) {
4+
long long ans = 0;
5+
unordered_map<int, int> pre;
6+
for (int x : nums) {
7+
unordered_map<int, int> cur;
8+
for (auto& [y, v] : pre) {
9+
cur[x & y] += v;
10+
}
11+
cur[x]++;
12+
ans += cur[k];
13+
pre = cur;
14+
}
15+
return ans;
16+
}
17+
};
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
func countSubarrays(nums []int, k int) (ans int64) {
2+
pre := map[int]int{}
3+
for _, x := range nums {
4+
cur := map[int]int{}
5+
for y, v := range pre {
6+
cur[x&y] += v
7+
}
8+
cur[x]++
9+
ans += int64(cur[k])
10+
pre = cur
11+
}
12+
return
13+
}
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
class Solution {
2+
public long countSubarrays(int[] nums, int k) {
3+
long ans = 0;
4+
Map<Integer, Integer> pre = new HashMap<>();
5+
for (int x : nums) {
6+
Map<Integer, Integer> cur = new HashMap<>();
7+
for (var e : pre.entrySet()) {
8+
int y = e.getKey(), v = e.getValue();
9+
cur.merge(x & y, v, Integer::sum);
10+
}
11+
cur.merge(x, 1, Integer::sum);
12+
ans += cur.getOrDefault(k, 0);
13+
pre = cur;
14+
}
15+
return ans;
16+
}
17+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
class Solution:
2+
def countSubarrays(self, nums: List[int], k: int) -> int:
3+
ans = 0
4+
pre = Counter()
5+
for x in nums:
6+
cur = Counter()
7+
for y, v in pre.items():
8+
cur[x & y] += v
9+
cur[x] += 1
10+
ans += cur[k]
11+
pre = cur
12+
return ans
Lines changed: 15 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
function countSubarrays(nums: number[], k: number): number {
2+
let ans = 0;
3+
let pre = new Map<number, number>();
4+
for (const x of nums) {
5+
const cur = new Map<number, number>();
6+
for (const [y, v] of pre) {
7+
const z = x & y;
8+
cur.set(z, (cur.get(z) || 0) + v);
9+
}
10+
cur.set(x, (cur.get(x) || 0) + 1);
11+
ans += cur.get(k) || 0;
12+
pre = cur;
13+
}
14+
return ans;
15+
}

0 commit comments

Comments
 (0)