Skip to content

Commit bd06665

Browse files
authored
feat: add solutions to lc problem: No.2197 (#2640)
No.2198.Number of Single Divisor Triplets
1 parent e23ae77 commit bd06665

File tree

7 files changed

+333
-263
lines changed

7 files changed

+333
-263
lines changed

solution/2100-2199/2198.Number of Single Divisor Triplets/README.md

Lines changed: 116 additions & 88 deletions
Original file line numberDiff line numberDiff line change
@@ -58,68 +58,69 @@
5858

5959
## 解法
6060

61-
### 方法一
61+
### 方法一:计数 + 枚举
62+
63+
我们注意到,数组 $\textit{nums}$ 的元素的范围是 $[1, 100]$,因此我们可以枚举三个数 $a, b, c$,其中 $a, b, c \in [1, 100]$,然后判断 $a + b + c$ 是否只能被 $a, b, c$ 中的一个数整除。如果是,则我们可以计算出以 $a, b, c$ 为元素的单因数三元组的个数。具体计算方法如下:
64+
65+
- 如果 $a = b$,那么以 $a, b, c$ 为元素的单因数三元组的个数为 $x \times (x - 1) \times z$,其中 $x$, $y$, $z$ 分别表示 $a$, $b$, $c$ 在数组 $\textit{nums}$ 中出现的次数。
66+
- 如果 $a = c$,那么以 $a, b, c$ 为元素的单因数三元组的个数为 $x \times (x - 1) \times y$。
67+
- 如果 $b = c$,那么以 $a, b, c$ 为元素的单因数三元组的个数为 $x \times y \times (y - 1)$。
68+
- 如果 $a, b, c$ 互不相等,那么以 $a, b, c$ 为元素的单因数三元组的个数为 $x \times y \times z$。
69+
70+
最后,我们将所有的单因数三元组的个数相加即可。
71+
72+
时间复杂度 $O(M^3)$,空间复杂度 $O(M)$。其中 $M$ 为数组 $\textit{nums}$ 中元素的取值范围。
6273

6374
<!-- tabs:start -->
6475

6576
```python
6677
class Solution:
6778
def singleDivisorTriplet(self, nums: List[int]) -> int:
68-
def check(a, b, c):
69-
s = a + b + c
70-
return sum(s % x == 0 for x in [a, b, c]) == 1
71-
72-
counter = Counter(nums)
79+
cnt = Counter(nums)
7380
ans = 0
74-
for a, cnt1 in counter.items():
75-
for b, cnt2 in counter.items():
76-
for c, cnt3 in counter.items():
77-
if check(a, b, c):
81+
for a, x in cnt.items():
82+
for b, y in cnt.items():
83+
for c, z in cnt.items():
84+
s = a + b + c
85+
if sum(s % v == 0 for v in (a, b, c)) == 1:
7886
if a == b:
79-
ans += cnt1 * (cnt1 - 1) * cnt3
87+
ans += x * (x - 1) * z
8088
elif a == c:
81-
ans += cnt1 * (cnt1 - 1) * cnt2
89+
ans += x * (x - 1) * y
8290
elif b == c:
83-
ans += cnt1 * cnt2 * (cnt2 - 1)
91+
ans += x * y * (y - 1)
8492
else:
85-
ans += cnt1 * cnt2 * cnt3
93+
ans += x * y * z
8694
return ans
8795
```
8896

8997
```java
9098
class Solution {
9199
public long singleDivisorTriplet(int[] nums) {
92-
int[] counter = new int[101];
100+
int[] cnt = new int[101];
93101
for (int x : nums) {
94-
++counter[x];
102+
++cnt[x];
95103
}
96104
long ans = 0;
97-
for (int i = 1; i <= 100; ++i) {
98-
for (int j = 1; j <= 100; ++j) {
99-
for (int k = 1; k <= 100; ++k) {
100-
int cnt1 = counter[i], cnt2 = counter[j], cnt3 = counter[k];
101-
int s = i + j + k;
102-
int cnt = 0;
103-
if (s % i == 0) {
104-
++cnt;
105-
}
106-
if (s % j == 0) {
107-
++cnt;
108-
}
109-
if (s % k == 0) {
110-
++cnt;
111-
}
112-
if (cnt != 1) {
113-
continue;
114-
}
115-
if (i == j) {
116-
ans += (long) cnt1 * (cnt1 - 1) * cnt3;
117-
} else if (i == k) {
118-
ans += (long) cnt1 * (cnt1 - 1) * cnt2;
119-
} else if (j == k) {
120-
ans += (long) cnt1 * cnt2 * (cnt2 - 1);
121-
} else {
122-
ans += (long) cnt1 * cnt2 * cnt3;
105+
for (int a = 1; a <= 100; ++a) {
106+
for (int b = 1; b <= 100; ++b) {
107+
for (int c = 1; c <= 100; ++c) {
108+
int s = a + b + c;
109+
int x = cnt[a], y = cnt[b], z = cnt[c];
110+
int t = 0;
111+
t += s % a == 0 ? 1 : 0;
112+
t += s % b == 0 ? 1 : 0;
113+
t += s % c == 0 ? 1 : 0;
114+
if (t == 1) {
115+
if (a == b) {
116+
ans += 1L * x * (x - 1) * z;
117+
} else if (a == c) {
118+
ans += 1L * x * (x - 1) * y;
119+
} else if (b == c) {
120+
ans += 1L * x * y * (y - 1);
121+
} else {
122+
ans += 1L * x * y * z;
123+
}
123124
}
124125
}
125126
}
@@ -133,24 +134,28 @@ class Solution {
133134
class Solution {
134135
public:
135136
long long singleDivisorTriplet(vector<int>& nums) {
136-
vector<int> counter(101);
137-
for (int& x : nums) ++counter[x];
137+
int cnt[101]{};
138+
for (int x : nums) {
139+
++cnt[x];
140+
}
138141
long long ans = 0;
139-
for (int i = 1; i <= 100; ++i) {
140-
for (int j = 1; j <= 100; ++j) {
141-
for (int k = 1; k <= 100; ++k) {
142-
int cnt1 = counter[i], cnt2 = counter[j], cnt3 = counter[k];
143-
int s = i + j + k;
144-
int cnt = (s % i == 0) + (s % j == 0) + (s % k == 0);
145-
if (cnt != 1) continue;
146-
if (i == j)
147-
ans += 1ll * cnt1 * (cnt1 - 1) * cnt3;
148-
else if (i == k)
149-
ans += 1ll * cnt1 * (cnt1 - 1) * cnt2;
150-
else if (j == k)
151-
ans += 1ll * cnt1 * cnt2 * (cnt2 - 1);
152-
else
153-
ans += 1ll * cnt1 * cnt2 * cnt3;
142+
for (int a = 1; a <= 100; ++a) {
143+
for (int b = 1; b <= 100; ++b) {
144+
for (int c = 1; c <= 100; ++c) {
145+
int s = a + b + c;
146+
int x = cnt[a], y = cnt[b], z = cnt[c];
147+
int t = (s % a == 0) + (s % b == 0) + (s % c == 0);
148+
if (t == 1) {
149+
if (a == b) {
150+
ans += 1LL * x * (x - 1) * z;
151+
} else if (a == c) {
152+
ans += 1LL * x * (x - 1) * y;
153+
} else if (b == c) {
154+
ans += 1LL * x * y * (y - 1);
155+
} else {
156+
ans += 1LL * x * y * z;
157+
}
158+
}
154159
}
155160
}
156161
}
@@ -160,45 +165,68 @@ public:
160165
```
161166
162167
```go
163-
func singleDivisorTriplet(nums []int) int64 {
164-
counter := make([]int, 101)
168+
func singleDivisorTriplet(nums []int) (ans int64) {
169+
cnt := [101]int{}
165170
for _, x := range nums {
166-
counter[x]++
171+
cnt[x]++
167172
}
168-
var ans int64
169-
check := func(a, b, c int) bool {
170-
s := a + b + c
171-
cnt := 0
172-
if s%a == 0 {
173-
cnt++
173+
f := func(a, b int) int {
174+
if a%b == 0 {
175+
return 1
174176
}
175-
if s%b == 0 {
176-
cnt++
177-
}
178-
if s%c == 0 {
179-
cnt++
180-
}
181-
return cnt == 1
177+
return 0
182178
}
183-
for i := 1; i <= 100; i++ {
184-
for j := 1; j <= 100; j++ {
185-
for k := 1; k <= 100; k++ {
186-
if check(i, j, k) {
187-
cnt1, cnt2, cnt3 := counter[i], counter[j], counter[k]
188-
if i == j {
189-
ans += int64(cnt1 * (cnt1 - 1) * cnt3)
190-
} else if i == k {
191-
ans += int64(cnt1 * (cnt1 - 1) * cnt2)
192-
} else if j == k {
193-
ans += int64(cnt1 * cnt2 * (cnt2 - 1))
179+
for a := 1; a <= 100; a++ {
180+
for b := 1; b <= 100; b++ {
181+
for c := 1; c <= 100; c++ {
182+
s := a + b + c
183+
t := f(s, a) + f(s, b) + f(s, c)
184+
if t == 1 {
185+
if a == b {
186+
ans += int64(cnt[a] * (cnt[a] - 1) * cnt[c])
187+
} else if a == c {
188+
ans += int64(cnt[a] * (cnt[a] - 1) * cnt[b])
189+
} else if b == c {
190+
ans += int64(cnt[b] * (cnt[b] - 1) * cnt[a])
194191
} else {
195-
ans += int64(cnt1 * cnt2 * cnt3)
192+
ans += int64(cnt[a] * cnt[b] * cnt[c])
196193
}
197194
}
198195
}
199196
}
200197
}
201-
return ans
198+
return
199+
}
200+
```
201+
202+
```ts
203+
function singleDivisorTriplet(nums: number[]): number {
204+
const cnt: number[] = Array(101).fill(0);
205+
for (const x of nums) {
206+
++cnt[x];
207+
}
208+
let ans = 0;
209+
const f = (a: number, b: number) => (a % b === 0 ? 1 : 0);
210+
for (let a = 1; a <= 100; ++a) {
211+
for (let b = 1; b <= 100; ++b) {
212+
for (let c = 1; c <= 100; ++c) {
213+
const s = a + b + c;
214+
const t = f(s, a) + f(s, b) + f(s, c);
215+
if (t === 1) {
216+
if (a === b) {
217+
ans += cnt[a] * (cnt[a] - 1) * cnt[c];
218+
} else if (a === c) {
219+
ans += cnt[a] * (cnt[a] - 1) * cnt[b];
220+
} else if (b === c) {
221+
ans += cnt[b] * (cnt[b] - 1) * cnt[a];
222+
} else {
223+
ans += cnt[a] * cnt[b] * cnt[c];
224+
}
225+
}
226+
}
227+
}
228+
}
229+
return ans;
202230
}
203231
```
204232

0 commit comments

Comments
 (0)