题目
个人思路
个人思路考虑的是先将它们计数出来每一个元素的个数,然后从set(A)取不重复有序的i,j,k:
然后分两种情况:i,j,k中是否有重复:
没有重复直接cnt[i]*cnt[j]*cnt[k]即可。
如果有重复,需要验证元素量是否足够,然后对重复元素递减-1相乘。
这样的效率较低。
其他方案
class Solution:
def threeSumMulti(self, A, target):
c = collections.Counter(A) # 直接就能生成Counter,不需要自己去for循环实现。
res = 0
for i, j in itertools.combinations_with_replacement(c, 2):
k = target - i - j
if i == j == k: res += c[i] * (c[i] - 1) * (c[i] - 2) / 6 # 有三个数相同i,j i,如果没有第三个会直接计算为0。
elif i == j != k: res += c[i] * (c[i] - 1) / 2 * c[k] # 有两个数相同。
elif k > i and k > j: res += c[i] * c[j] * c[k] # 三个数不同大小。
# 其他情况不予添加。
return int(res % (10**9 + 7))
直接combinations(A会出现以下的结果)
A = [1,1,2,2,3,3,4,4,5,5]
>>> for i,j in itertools.combinations_with_replacement(A,2):
print((i,j),end=' ')
(1, 1) (1, 1) (1, 2) (1, 2) (1, 3) (1, 3) (1, 4) (1, 4) (1, 5) (1, 5) (1, 1) (1, 2) (1, 2) (1, 3) (1, 3) (1, 4) (1, 4) (1, 5) (1, 5) (2, 2) (2, 2) (2, 3) (2, 3) (2, 4) (2, 4) (2, 5) (2, 5) (2, 2) (2, 3) (2, 3) (2, 4) (2, 4) (2, 5) (2, 5) (3, 3) (3, 3) (3, 4) (3, 4) (3, 5) (3, 5) (3, 3) (3, 4) (3, 4) (3, 5) (3, 5) (4, 4) (4, 4) (4, 5) (4, 5) (4, 4) (4, 5) (4, 5) (5, 5) (5, 5) (5, 5)
但它,combinations的是c,相当于:
A = [1,2,3,4,5]
>>> for i,j in itertools.combinations_with_replacement(A,2):
print((i,j),end=' ')
(1, 1) (1, 2) (1, 3) (1, 4) (1, 5) (2, 2) (2, 3) (2, 4) (2, 5) (3, 3) (3, 4) (3, 5) (4, 4) (4, 5) (5, 5)
其他解法
对数组排列中,使用i、j、k的循环。
class Solution:
def threeSumMulti(self, A: List[int], target: int) -> int:
ans = 0
mod = 10 ** 9 + 7
count = collections.Counter(A)
keys = sorted(count)
for i in range(len(keys) ):
T = target - keys[i]
j, k = i, len(keys) - 1
while j <= k:
if keys[j] + keys[k] < T:
j += 1
elif keys[j] + keys[k] > T:
k -= 1
else:
x, y, z = keys[i], keys[j], keys[k]
if i < j < k:
ans += count[x] * count[y] * count[z]
elif i == j < k:
ans += count[x] * ( (count[x] - 1) / 2) * count[z]
elif i < j == k:
ans += count[x] * count[y] * (count[y] - 1) / 2
else: # i == j == k
ans += count[x] * (count[x] - 1) * (count[x] - 2) / 6
j += 1
k -= 1
return int(ans % mod)