Skip to content

Commit 6454943

Browse files
authored
feat: add solutions to lc problem: No.2261 (doocs#3801)
No.2261.K Divisible Elements Subarrays
1 parent 9a9eb78 commit 6454943

File tree

8 files changed

+155
-108
lines changed

8 files changed

+155
-108
lines changed

Diff for: solution/2200-2299/2261.K Divisible Elements Subarrays/README.md

+51-32
Original file line numberDiff line numberDiff line change
@@ -82,11 +82,11 @@ nums 中的所有元素都可以被 p = 1 整除。
8282

8383
<!-- solution:start -->
8484

85-
### 方法一:哈希表 + 枚举
85+
### 方法一:枚举 + 字符串哈希
8686

87-
我们可以枚举子数组的左右端点 $i$ 和 $j$,其中 $0 \leq i \leq j < n$。对于每个子数组 $nums[i,..j]$,我们可以统计其中可以被 $p$ 整除的元素的个数 $cnt$,如果 $cnt \leq k$,则该子数组满足条件。我们将所有满足条件的子数组的元素序列作为字符串存入哈希表中,最后哈希表中的元素个数即为答案
87+
我们可以枚举子数组的左端点 $i$,再在 $[i, n)$ 的范围内枚举子数组的右端点 $j$,在枚举右端点的过程中,我们通过双哈希的方式,将子数组的哈希值存入集合中,最后返回集合的大小即可
8888

89-
时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组 $nums$ 的长度
89+
时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组的长度
9090

9191
<!-- tabs:start -->
9292

@@ -95,15 +95,19 @@ nums 中的所有元素都可以被 p = 1 整除。
9595
```python
9696
class Solution:
9797
def countDistinct(self, nums: List[int], k: int, p: int) -> int:
98-
n = len(nums)
9998
s = set()
99+
n = len(nums)
100+
base1, base2 = 131, 13331
101+
mod1, mod2 = 10**9 + 7, 10**9 + 9
100102
for i in range(n):
101-
cnt = 0
103+
h1 = h2 = cnt = 0
102104
for j in range(i, n):
103105
cnt += nums[j] % p == 0
104106
if cnt > k:
105107
break
106-
s.add(tuple(nums[i : j + 1]))
108+
h1 = (h1 * base1 + nums[j]) % mod1
109+
h2 = (h2 * base2 + nums[j]) % mod2
110+
s.add(h1 << 32 | h2)
107111
return len(s)
108112
```
109113

@@ -112,17 +116,21 @@ class Solution:
112116
```java
113117
class Solution {
114118
public int countDistinct(int[] nums, int k, int p) {
119+
Set<Long> s = new HashSet<>();
115120
int n = nums.length;
116-
Set<String> s = new HashSet<>();
121+
int base1 = 131, base2 = 13331;
122+
int mod1 = (int) 1e9 + 7, mod2 = (int) 1e9 + 9;
117123
for (int i = 0; i < n; ++i) {
124+
long h1 = 0, h2 = 0;
118125
int cnt = 0;
119-
String t = "";
120126
for (int j = i; j < n; ++j) {
121-
if (nums[j] % p == 0 && ++cnt > k) {
127+
cnt += nums[j] % p == 0 ? 1 : 0;
128+
if (cnt > k) {
122129
break;
123130
}
124-
t += nums[j] + ",";
125-
s.add(t);
131+
h1 = (h1 * base1 + nums[j]) % mod1;
132+
h2 = (h2 * base2 + nums[j]) % mod2;
133+
s.add(h1 << 32 | h2);
126134
}
127135
}
128136
return s.size();
@@ -136,17 +144,21 @@ class Solution {
136144
class Solution {
137145
public:
138146
int countDistinct(vector<int>& nums, int k, int p) {
139-
unordered_set<string> s;
147+
unordered_set<long long> s;
140148
int n = nums.size();
149+
int base1 = 131, base2 = 13331;
150+
int mod1 = 1e9 + 7, mod2 = 1e9 + 9;
141151
for (int i = 0; i < n; ++i) {
152+
long long h1 = 0, h2 = 0;
142153
int cnt = 0;
143-
string t;
144154
for (int j = i; j < n; ++j) {
145-
if (nums[j] % p == 0 && ++cnt > k) {
155+
cnt += nums[j] % p == 0;
156+
if (cnt > k) {
146157
break;
147158
}
148-
t += to_string(nums[j]) + ",";
149-
s.insert(t);
159+
h1 = (h1 * base1 + nums[j]) % mod1;
160+
h2 = (h2 * base2 + nums[j]) % mod2;
161+
s.insert(h1 << 32 | h2);
150162
}
151163
}
152164
return s.size();
@@ -158,18 +170,21 @@ public:
158170
159171
```go
160172
func countDistinct(nums []int, k int, p int) int {
161-
s := map[string]struct{}{}
173+
s := map[int]bool{}
174+
base1, base2 := 131, 13331
175+
mod1, mod2 := 1000000007, 1000000009
162176
for i := range nums {
163-
cnt, t := 0, ""
164-
for _, x := range nums[i:] {
165-
if x%p == 0 {
177+
h1, h2, cnt := 0, 0, 0
178+
for j := i; j < len(nums); j++ {
179+
if nums[j]%p == 0 {
166180
cnt++
167181
if cnt > k {
168182
break
169183
}
170184
}
171-
t += string(x) + ","
172-
s[t] = struct{}{}
185+
h1 = (h1*base1 + nums[j]) % mod1
186+
h2 = (h2*base2 + nums[j]) % mod2
187+
s[h1<<32|h2] = true
173188
}
174189
}
175190
return len(s)
@@ -180,17 +195,21 @@ func countDistinct(nums []int, k int, p int) int {
180195

181196
```ts
182197
function countDistinct(nums: number[], k: number, p: number): number {
183-
const n = nums.length;
184-
const s = new Set();
185-
for (let i = 0; i < n; ++i) {
186-
let cnt = 0;
187-
let t = '';
188-
for (let j = i; j < n; ++j) {
189-
if (nums[j] % p === 0 && ++cnt > k) {
190-
break;
198+
const s = new Set<bigint>();
199+
const [base1, base2] = [131, 13331];
200+
const [mod1, mod2] = [1000000007, 1000000009];
201+
for (let i = 0; i < nums.length; i++) {
202+
let [h1, h2, cnt] = [0, 0, 0];
203+
for (let j = i; j < nums.length; j++) {
204+
if (nums[j] % p === 0) {
205+
cnt++;
206+
if (cnt > k) {
207+
break;
208+
}
191209
}
192-
t += nums[j].toString() + ',';
193-
s.add(t);
210+
h1 = (h1 * base1 + nums[j]) % mod1;
211+
h2 = (h2 * base2 + nums[j]) % mod2;
212+
s.add((BigInt(h1) << 32n) | BigInt(h2));
194213
}
195214
}
196215
return s.size;

Diff for: solution/2200-2299/2261.K Divisible Elements Subarrays/README_EN.md

+53-30
Original file line numberDiff line numberDiff line change
@@ -79,7 +79,11 @@ Since all subarrays are distinct, the total number of subarrays satisfying all t
7979

8080
<!-- solution:start -->
8181

82-
### Solution 1
82+
### Solution 1: Enumeration + String Hashing
83+
84+
We can enumerate the left endpoint $i$ of the subarray, and then enumerate the right endpoint $j$ in the range $[i, n)$. During the enumeration of the right endpoint, we use double hashing to store the hash value of the subarray into a set. Finally, we return the size of the set.
85+
86+
The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the array.
8387

8488
<!-- tabs:start -->
8589

@@ -88,15 +92,19 @@ Since all subarrays are distinct, the total number of subarrays satisfying all t
8892
```python
8993
class Solution:
9094
def countDistinct(self, nums: List[int], k: int, p: int) -> int:
91-
n = len(nums)
9295
s = set()
96+
n = len(nums)
97+
base1, base2 = 131, 13331
98+
mod1, mod2 = 10**9 + 7, 10**9 + 9
9399
for i in range(n):
94-
cnt = 0
100+
h1 = h2 = cnt = 0
95101
for j in range(i, n):
96102
cnt += nums[j] % p == 0
97103
if cnt > k:
98104
break
99-
s.add(tuple(nums[i : j + 1]))
105+
h1 = (h1 * base1 + nums[j]) % mod1
106+
h2 = (h2 * base2 + nums[j]) % mod2
107+
s.add(h1 << 32 | h2)
100108
return len(s)
101109
```
102110

@@ -105,17 +113,21 @@ class Solution:
105113
```java
106114
class Solution {
107115
public int countDistinct(int[] nums, int k, int p) {
116+
Set<Long> s = new HashSet<>();
108117
int n = nums.length;
109-
Set<String> s = new HashSet<>();
118+
int base1 = 131, base2 = 13331;
119+
int mod1 = (int) 1e9 + 7, mod2 = (int) 1e9 + 9;
110120
for (int i = 0; i < n; ++i) {
121+
long h1 = 0, h2 = 0;
111122
int cnt = 0;
112-
String t = "";
113123
for (int j = i; j < n; ++j) {
114-
if (nums[j] % p == 0 && ++cnt > k) {
124+
cnt += nums[j] % p == 0 ? 1 : 0;
125+
if (cnt > k) {
115126
break;
116127
}
117-
t += nums[j] + ",";
118-
s.add(t);
128+
h1 = (h1 * base1 + nums[j]) % mod1;
129+
h2 = (h2 * base2 + nums[j]) % mod2;
130+
s.add(h1 << 32 | h2);
119131
}
120132
}
121133
return s.size();
@@ -129,17 +141,21 @@ class Solution {
129141
class Solution {
130142
public:
131143
int countDistinct(vector<int>& nums, int k, int p) {
132-
unordered_set<string> s;
144+
unordered_set<long long> s;
133145
int n = nums.size();
146+
int base1 = 131, base2 = 13331;
147+
int mod1 = 1e9 + 7, mod2 = 1e9 + 9;
134148
for (int i = 0; i < n; ++i) {
149+
long long h1 = 0, h2 = 0;
135150
int cnt = 0;
136-
string t;
137151
for (int j = i; j < n; ++j) {
138-
if (nums[j] % p == 0 && ++cnt > k) {
152+
cnt += nums[j] % p == 0;
153+
if (cnt > k) {
139154
break;
140155
}
141-
t += to_string(nums[j]) + ",";
142-
s.insert(t);
156+
h1 = (h1 * base1 + nums[j]) % mod1;
157+
h2 = (h2 * base2 + nums[j]) % mod2;
158+
s.insert(h1 << 32 | h2);
143159
}
144160
}
145161
return s.size();
@@ -151,18 +167,21 @@ public:
151167
152168
```go
153169
func countDistinct(nums []int, k int, p int) int {
154-
s := map[string]struct{}{}
170+
s := map[int]bool{}
171+
base1, base2 := 131, 13331
172+
mod1, mod2 := 1000000007, 1000000009
155173
for i := range nums {
156-
cnt, t := 0, ""
157-
for _, x := range nums[i:] {
158-
if x%p == 0 {
174+
h1, h2, cnt := 0, 0, 0
175+
for j := i; j < len(nums); j++ {
176+
if nums[j]%p == 0 {
159177
cnt++
160178
if cnt > k {
161179
break
162180
}
163181
}
164-
t += string(x) + ","
165-
s[t] = struct{}{}
182+
h1 = (h1*base1 + nums[j]) % mod1
183+
h2 = (h2*base2 + nums[j]) % mod2
184+
s[h1<<32|h2] = true
166185
}
167186
}
168187
return len(s)
@@ -173,17 +192,21 @@ func countDistinct(nums []int, k int, p int) int {
173192

174193
```ts
175194
function countDistinct(nums: number[], k: number, p: number): number {
176-
const n = nums.length;
177-
const s = new Set();
178-
for (let i = 0; i < n; ++i) {
179-
let cnt = 0;
180-
let t = '';
181-
for (let j = i; j < n; ++j) {
182-
if (nums[j] % p === 0 && ++cnt > k) {
183-
break;
195+
const s = new Set<bigint>();
196+
const [base1, base2] = [131, 13331];
197+
const [mod1, mod2] = [1000000007, 1000000009];
198+
for (let i = 0; i < nums.length; i++) {
199+
let [h1, h2, cnt] = [0, 0, 0];
200+
for (let j = i; j < nums.length; j++) {
201+
if (nums[j] % p === 0) {
202+
cnt++;
203+
if (cnt > k) {
204+
break;
205+
}
184206
}
185-
t += nums[j].toString() + ',';
186-
s.add(t);
207+
h1 = (h1 * base1 + nums[j]) % mod1;
208+
h2 = (h2 * base2 + nums[j]) % mod2;
209+
s.add((BigInt(h1) << 32n) | BigInt(h2));
187210
}
188211
}
189212
return s.size;
Original file line numberDiff line numberDiff line change
@@ -1,19 +1,23 @@
11
class Solution {
22
public:
33
int countDistinct(vector<int>& nums, int k, int p) {
4-
unordered_set<string> s;
4+
unordered_set<long long> s;
55
int n = nums.size();
6+
int base1 = 131, base2 = 13331;
7+
int mod1 = 1e9 + 7, mod2 = 1e9 + 9;
68
for (int i = 0; i < n; ++i) {
9+
long long h1 = 0, h2 = 0;
710
int cnt = 0;
8-
string t;
911
for (int j = i; j < n; ++j) {
10-
if (nums[j] % p == 0 && ++cnt > k) {
12+
cnt += nums[j] % p == 0;
13+
if (cnt > k) {
1114
break;
1215
}
13-
t += to_string(nums[j]) + ",";
14-
s.insert(t);
16+
h1 = (h1 * base1 + nums[j]) % mod1;
17+
h2 = (h2 * base2 + nums[j]) % mod2;
18+
s.insert(h1 << 32 | h2);
1519
}
1620
}
1721
return s.size();
1822
}
19-
};
23+
};
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,20 @@
11
func countDistinct(nums []int, k int, p int) int {
2-
s := map[string]struct{}{}
2+
s := map[int]bool{}
3+
base1, base2 := 131, 13331
4+
mod1, mod2 := 1000000007, 1000000009
35
for i := range nums {
4-
cnt, t := 0, ""
5-
for _, x := range nums[i:] {
6-
if x%p == 0 {
6+
h1, h2, cnt := 0, 0, 0
7+
for j := i; j < len(nums); j++ {
8+
if nums[j]%p == 0 {
79
cnt++
810
if cnt > k {
911
break
1012
}
1113
}
12-
t += string(x) + ","
13-
s[t] = struct{}{}
14+
h1 = (h1*base1 + nums[j]) % mod1
15+
h2 = (h2*base2 + nums[j]) % mod2
16+
s[h1<<32|h2] = true
1417
}
1518
}
1619
return len(s)
17-
}
20+
}
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,22 @@
11
class Solution {
22
public int countDistinct(int[] nums, int k, int p) {
3+
Set<Long> s = new HashSet<>();
34
int n = nums.length;
4-
Set<String> s = new HashSet<>();
5+
int base1 = 131, base2 = 13331;
6+
int mod1 = (int) 1e9 + 7, mod2 = (int) 1e9 + 9;
57
for (int i = 0; i < n; ++i) {
8+
long h1 = 0, h2 = 0;
69
int cnt = 0;
7-
String t = "";
810
for (int j = i; j < n; ++j) {
9-
if (nums[j] % p == 0 && ++cnt > k) {
11+
cnt += nums[j] % p == 0 ? 1 : 0;
12+
if (cnt > k) {
1013
break;
1114
}
12-
t += nums[j] + ",";
13-
s.add(t);
15+
h1 = (h1 * base1 + nums[j]) % mod1;
16+
h2 = (h2 * base2 + nums[j]) % mod2;
17+
s.add(h1 << 32 | h2);
1418
}
1519
}
1620
return s.size();
1721
}
18-
}
22+
}

0 commit comments

Comments
 (0)