diff --git a/solution/2200-2299/2261.K Divisible Elements Subarrays/README.md b/solution/2200-2299/2261.K Divisible Elements Subarrays/README.md index 33385681b8955..a29a23161cde5 100644 --- a/solution/2200-2299/2261.K Divisible Elements Subarrays/README.md +++ b/solution/2200-2299/2261.K Divisible Elements Subarrays/README.md @@ -82,11 +82,11 @@ nums 中的所有元素都可以被 p = 1 整除。 -### 方法一:哈希表 + 枚举 +### 方法一:枚举 + 字符串哈希 -我们可以枚举子数组的左右端点 $i$ 和 $j$,其中 $0 \leq i \leq j < n$。对于每个子数组 $nums[i,..j]$,我们可以统计其中可以被 $p$ 整除的元素的个数 $cnt$,如果 $cnt \leq k$,则该子数组满足条件。我们将所有满足条件的子数组的元素序列作为字符串存入哈希表中,最后哈希表中的元素个数即为答案。 +我们可以枚举子数组的左端点 $i$,再在 $[i, n)$ 的范围内枚举子数组的右端点 $j$,在枚举右端点的过程中,我们通过双哈希的方式,将子数组的哈希值存入集合中,最后返回集合的大小即可。 -时间复杂度 $O(n^3)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组 $nums$ 的长度。 +时间复杂度 $O(n^2)$,空间复杂度 $O(n^2)$。其中 $n$ 为数组的长度。 @@ -95,15 +95,19 @@ nums 中的所有元素都可以被 p = 1 整除。 ```python class Solution: def countDistinct(self, nums: List[int], k: int, p: int) -> int: - n = len(nums) s = set() + n = len(nums) + base1, base2 = 131, 13331 + mod1, mod2 = 10**9 + 7, 10**9 + 9 for i in range(n): - cnt = 0 + h1 = h2 = cnt = 0 for j in range(i, n): cnt += nums[j] % p == 0 if cnt > k: break - s.add(tuple(nums[i : j + 1])) + h1 = (h1 * base1 + nums[j]) % mod1 + h2 = (h2 * base2 + nums[j]) % mod2 + s.add(h1 << 32 | h2) return len(s) ``` @@ -112,17 +116,21 @@ class Solution: ```java class Solution { public int countDistinct(int[] nums, int k, int p) { + Set s = new HashSet<>(); int n = nums.length; - Set s = new HashSet<>(); + int base1 = 131, base2 = 13331; + int mod1 = (int) 1e9 + 7, mod2 = (int) 1e9 + 9; for (int i = 0; i < n; ++i) { + long h1 = 0, h2 = 0; int cnt = 0; - String t = ""; for (int j = i; j < n; ++j) { - if (nums[j] % p == 0 && ++cnt > k) { + cnt += nums[j] % p == 0 ? 1 : 0; + if (cnt > k) { break; } - t += nums[j] + ","; - s.add(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.add(h1 << 32 | h2); } } return s.size(); @@ -136,17 +144,21 @@ class Solution { class Solution { public: int countDistinct(vector& nums, int k, int p) { - unordered_set s; + unordered_set s; int n = nums.size(); + int base1 = 131, base2 = 13331; + int mod1 = 1e9 + 7, mod2 = 1e9 + 9; for (int i = 0; i < n; ++i) { + long long h1 = 0, h2 = 0; int cnt = 0; - string t; for (int j = i; j < n; ++j) { - if (nums[j] % p == 0 && ++cnt > k) { + cnt += nums[j] % p == 0; + if (cnt > k) { break; } - t += to_string(nums[j]) + ","; - s.insert(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.insert(h1 << 32 | h2); } } return s.size(); @@ -158,18 +170,21 @@ public: ```go func countDistinct(nums []int, k int, p int) int { - s := map[string]struct{}{} + s := map[int]bool{} + base1, base2 := 131, 13331 + mod1, mod2 := 1000000007, 1000000009 for i := range nums { - cnt, t := 0, "" - for _, x := range nums[i:] { - if x%p == 0 { + h1, h2, cnt := 0, 0, 0 + for j := i; j < len(nums); j++ { + if nums[j]%p == 0 { cnt++ if cnt > k { break } } - t += string(x) + "," - s[t] = struct{}{} + h1 = (h1*base1 + nums[j]) % mod1 + h2 = (h2*base2 + nums[j]) % mod2 + s[h1<<32|h2] = true } } return len(s) @@ -180,17 +195,21 @@ func countDistinct(nums []int, k int, p int) int { ```ts function countDistinct(nums: number[], k: number, p: number): number { - const n = nums.length; - const s = new Set(); - for (let i = 0; i < n; ++i) { - let cnt = 0; - let t = ''; - for (let j = i; j < n; ++j) { - if (nums[j] % p === 0 && ++cnt > k) { - break; + const s = new Set(); + const [base1, base2] = [131, 13331]; + const [mod1, mod2] = [1000000007, 1000000009]; + for (let i = 0; i < nums.length; i++) { + let [h1, h2, cnt] = [0, 0, 0]; + for (let j = i; j < nums.length; j++) { + if (nums[j] % p === 0) { + cnt++; + if (cnt > k) { + break; + } } - t += nums[j].toString() + ','; - s.add(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.add((BigInt(h1) << 32n) | BigInt(h2)); } } return s.size; diff --git a/solution/2200-2299/2261.K Divisible Elements Subarrays/README_EN.md b/solution/2200-2299/2261.K Divisible Elements Subarrays/README_EN.md index 4751c1686cfdb..73fc8670c7ae7 100644 --- a/solution/2200-2299/2261.K Divisible Elements Subarrays/README_EN.md +++ b/solution/2200-2299/2261.K Divisible Elements Subarrays/README_EN.md @@ -79,7 +79,11 @@ Since all subarrays are distinct, the total number of subarrays satisfying all t -### Solution 1 +### Solution 1: Enumeration + String Hashing + +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. + +The time complexity is $O(n^2)$, and the space complexity is $O(n^2)$. Here, $n$ is the length of the array. @@ -88,15 +92,19 @@ Since all subarrays are distinct, the total number of subarrays satisfying all t ```python class Solution: def countDistinct(self, nums: List[int], k: int, p: int) -> int: - n = len(nums) s = set() + n = len(nums) + base1, base2 = 131, 13331 + mod1, mod2 = 10**9 + 7, 10**9 + 9 for i in range(n): - cnt = 0 + h1 = h2 = cnt = 0 for j in range(i, n): cnt += nums[j] % p == 0 if cnt > k: break - s.add(tuple(nums[i : j + 1])) + h1 = (h1 * base1 + nums[j]) % mod1 + h2 = (h2 * base2 + nums[j]) % mod2 + s.add(h1 << 32 | h2) return len(s) ``` @@ -105,17 +113,21 @@ class Solution: ```java class Solution { public int countDistinct(int[] nums, int k, int p) { + Set s = new HashSet<>(); int n = nums.length; - Set s = new HashSet<>(); + int base1 = 131, base2 = 13331; + int mod1 = (int) 1e9 + 7, mod2 = (int) 1e9 + 9; for (int i = 0; i < n; ++i) { + long h1 = 0, h2 = 0; int cnt = 0; - String t = ""; for (int j = i; j < n; ++j) { - if (nums[j] % p == 0 && ++cnt > k) { + cnt += nums[j] % p == 0 ? 1 : 0; + if (cnt > k) { break; } - t += nums[j] + ","; - s.add(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.add(h1 << 32 | h2); } } return s.size(); @@ -129,17 +141,21 @@ class Solution { class Solution { public: int countDistinct(vector& nums, int k, int p) { - unordered_set s; + unordered_set s; int n = nums.size(); + int base1 = 131, base2 = 13331; + int mod1 = 1e9 + 7, mod2 = 1e9 + 9; for (int i = 0; i < n; ++i) { + long long h1 = 0, h2 = 0; int cnt = 0; - string t; for (int j = i; j < n; ++j) { - if (nums[j] % p == 0 && ++cnt > k) { + cnt += nums[j] % p == 0; + if (cnt > k) { break; } - t += to_string(nums[j]) + ","; - s.insert(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.insert(h1 << 32 | h2); } } return s.size(); @@ -151,18 +167,21 @@ public: ```go func countDistinct(nums []int, k int, p int) int { - s := map[string]struct{}{} + s := map[int]bool{} + base1, base2 := 131, 13331 + mod1, mod2 := 1000000007, 1000000009 for i := range nums { - cnt, t := 0, "" - for _, x := range nums[i:] { - if x%p == 0 { + h1, h2, cnt := 0, 0, 0 + for j := i; j < len(nums); j++ { + if nums[j]%p == 0 { cnt++ if cnt > k { break } } - t += string(x) + "," - s[t] = struct{}{} + h1 = (h1*base1 + nums[j]) % mod1 + h2 = (h2*base2 + nums[j]) % mod2 + s[h1<<32|h2] = true } } return len(s) @@ -173,17 +192,21 @@ func countDistinct(nums []int, k int, p int) int { ```ts function countDistinct(nums: number[], k: number, p: number): number { - const n = nums.length; - const s = new Set(); - for (let i = 0; i < n; ++i) { - let cnt = 0; - let t = ''; - for (let j = i; j < n; ++j) { - if (nums[j] % p === 0 && ++cnt > k) { - break; + const s = new Set(); + const [base1, base2] = [131, 13331]; + const [mod1, mod2] = [1000000007, 1000000009]; + for (let i = 0; i < nums.length; i++) { + let [h1, h2, cnt] = [0, 0, 0]; + for (let j = i; j < nums.length; j++) { + if (nums[j] % p === 0) { + cnt++; + if (cnt > k) { + break; + } } - t += nums[j].toString() + ','; - s.add(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.add((BigInt(h1) << 32n) | BigInt(h2)); } } return s.size; diff --git a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.cpp b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.cpp index 26affdf4489e5..aad74d4934ba6 100644 --- a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.cpp +++ b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.cpp @@ -1,19 +1,23 @@ class Solution { public: int countDistinct(vector& nums, int k, int p) { - unordered_set s; + unordered_set s; int n = nums.size(); + int base1 = 131, base2 = 13331; + int mod1 = 1e9 + 7, mod2 = 1e9 + 9; for (int i = 0; i < n; ++i) { + long long h1 = 0, h2 = 0; int cnt = 0; - string t; for (int j = i; j < n; ++j) { - if (nums[j] % p == 0 && ++cnt > k) { + cnt += nums[j] % p == 0; + if (cnt > k) { break; } - t += to_string(nums[j]) + ","; - s.insert(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.insert(h1 << 32 | h2); } } return s.size(); } -}; \ No newline at end of file +}; diff --git a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.go b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.go index 8014228ff8cce..8601bcfa6d08a 100644 --- a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.go +++ b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.go @@ -1,17 +1,20 @@ func countDistinct(nums []int, k int, p int) int { - s := map[string]struct{}{} + s := map[int]bool{} + base1, base2 := 131, 13331 + mod1, mod2 := 1000000007, 1000000009 for i := range nums { - cnt, t := 0, "" - for _, x := range nums[i:] { - if x%p == 0 { + h1, h2, cnt := 0, 0, 0 + for j := i; j < len(nums); j++ { + if nums[j]%p == 0 { cnt++ if cnt > k { break } } - t += string(x) + "," - s[t] = struct{}{} + h1 = (h1*base1 + nums[j]) % mod1 + h2 = (h2*base2 + nums[j]) % mod2 + s[h1<<32|h2] = true } } return len(s) -} \ No newline at end of file +} diff --git a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.java b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.java index b5d04de687394..757529527b0ed 100644 --- a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.java +++ b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.java @@ -1,18 +1,22 @@ class Solution { public int countDistinct(int[] nums, int k, int p) { + Set s = new HashSet<>(); int n = nums.length; - Set s = new HashSet<>(); + int base1 = 131, base2 = 13331; + int mod1 = (int) 1e9 + 7, mod2 = (int) 1e9 + 9; for (int i = 0; i < n; ++i) { + long h1 = 0, h2 = 0; int cnt = 0; - String t = ""; for (int j = i; j < n; ++j) { - if (nums[j] % p == 0 && ++cnt > k) { + cnt += nums[j] % p == 0 ? 1 : 0; + if (cnt > k) { break; } - t += nums[j] + ","; - s.add(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.add(h1 << 32 | h2); } } return s.size(); } -} \ No newline at end of file +} diff --git a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.py b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.py index 44b2164c5ee2c..3f0eea89987e2 100644 --- a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.py +++ b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.py @@ -1,12 +1,16 @@ class Solution: def countDistinct(self, nums: List[int], k: int, p: int) -> int: - n = len(nums) s = set() + n = len(nums) + base1, base2 = 131, 13331 + mod1, mod2 = 10**9 + 7, 10**9 + 9 for i in range(n): - cnt = 0 + h1 = h2 = cnt = 0 for j in range(i, n): cnt += nums[j] % p == 0 if cnt > k: break - s.add(tuple(nums[i : j + 1])) + h1 = (h1 * base1 + nums[j]) % mod1 + h2 = (h2 * base2 + nums[j]) % mod2 + s.add(h1 << 32 | h2) return len(s) diff --git a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.ts b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.ts index a79e3493c435d..a94d4bd39654d 100644 --- a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.ts +++ b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution.ts @@ -1,15 +1,19 @@ function countDistinct(nums: number[], k: number, p: number): number { - const n = nums.length; - const s = new Set(); - for (let i = 0; i < n; ++i) { - let cnt = 0; - let t = ''; - for (let j = i; j < n; ++j) { - if (nums[j] % p === 0 && ++cnt > k) { - break; + const s = new Set(); + const [base1, base2] = [131, 13331]; + const [mod1, mod2] = [1000000007, 1000000009]; + for (let i = 0; i < nums.length; i++) { + let [h1, h2, cnt] = [0, 0, 0]; + for (let j = i; j < nums.length; j++) { + if (nums[j] % p === 0) { + cnt++; + if (cnt > k) { + break; + } } - t += nums[j].toString() + ','; - s.add(t); + h1 = (h1 * base1 + nums[j]) % mod1; + h2 = (h2 * base2 + nums[j]) % mod2; + s.add((BigInt(h1) << 32n) | BigInt(h2)); } } return s.size; diff --git a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution2.py b/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution2.py deleted file mode 100644 index e8d37001f1408..0000000000000 --- a/solution/2200-2299/2261.K Divisible Elements Subarrays/Solution2.py +++ /dev/null @@ -1,14 +0,0 @@ -class Solution: - def countDistinct(self, nums: List[int], k: int, p: int) -> int: - n = len(nums) - s = set() - for i in range(n): - cnt = 0 - t = "" - for x in nums[i:]: - cnt += x % p == 0 - if cnt > k: - break - t += str(x) + "," - s.add(t) - return len(s)