58
58
59
59
## 解法
60
60
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}$ 中元素的取值范围。
62
73
63
74
<!-- tabs:start -->
64
75
65
76
``` python
66
77
class Solution :
67
78
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)
73
80
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 :
78
86
if a == b:
79
- ans += cnt1 * (cnt1 - 1 ) * cnt3
87
+ ans += x * (x - 1 ) * z
80
88
elif a == c:
81
- ans += cnt1 * (cnt1 - 1 ) * cnt2
89
+ ans += x * (x - 1 ) * y
82
90
elif b == c:
83
- ans += cnt1 * cnt2 * (cnt2 - 1 )
91
+ ans += x * y * (y - 1 )
84
92
else :
85
- ans += cnt1 * cnt2 * cnt3
93
+ ans += x * y * z
86
94
return ans
87
95
```
88
96
89
97
``` java
90
98
class Solution {
91
99
public long singleDivisorTriplet (int [] nums ) {
92
- int [] counter = new int [101 ];
100
+ int [] cnt = new int [101 ];
93
101
for (int x : nums) {
94
- ++ counter [x];
102
+ ++ cnt [x];
95
103
}
96
104
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
+ }
123
124
}
124
125
}
125
126
}
@@ -133,24 +134,28 @@ class Solution {
133
134
class Solution {
134
135
public:
135
136
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
+ }
138
141
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
+ }
154
159
}
155
160
}
156
161
}
@@ -160,45 +165,68 @@ public:
160
165
```
161
166
162
167
```go
163
- func singleDivisorTriplet(nums []int) int64 {
164
- counter := make([ ]int, 101)
168
+ func singleDivisorTriplet(nums []int) (ans int64) {
169
+ cnt := [101 ]int{}
165
170
for _, x := range nums {
166
- counter [x]++
171
+ cnt [x]++
167
172
}
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
174
176
}
175
- if s%b == 0 {
176
- cnt++
177
- }
178
- if s%c == 0 {
179
- cnt++
180
- }
181
- return cnt == 1
177
+ return 0
182
178
}
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])
194
191
} else {
195
- ans += int64(cnt1 * cnt2 * cnt3 )
192
+ ans += int64(cnt[a] * cnt[b] * cnt[c] )
196
193
}
197
194
}
198
195
}
199
196
}
200
197
}
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 ;
202
230
}
203
231
```
204
232
0 commit comments