题目描述:
Given an integer array A, and an integer target, return the number of tuples i, j, k such that i < j < k and A[i] + A[j] + A[k] == target.
As the answer can be very large, return it modulo 10^9 + 7.
Example 1:
Input: A = [1,1,2,2,3,3,4,4,5,5], target = 8
Output: 20
Explanation:
Enumerating by the values (A[i], A[j], A[k]):
(1, 2, 5) occurs 8 times;
(1, 3, 4) occurs 8 times;
(2, 2, 4) occurs 2 times;
(2, 3, 3) occurs 2 times.
Example 2:
Input: A = [1,1,2,2,2,2], target = 5
Output: 12
Explanation:
A[i] = 1, A[j] = A[k] = 2 occurs 12 times:
We choose one 1 from [1,1] in 2 ways,
and two 2s from [2,2,2,2] in 6 ways.
Note:
1. 3 <= A.length <= 3000
2. 0 <= A[i] <= 100
3. 0 <= target <= 300
class Solution {
public:
int threeSumMulti(vector<int>& A, int target) {
//需要计算多个hash[x]的乘积,如果每个hash[x]都是int类型,得到的乘积已经溢出,再赋值给long long类型的result还是错误的结果
unordered_map<int,long long> hash;
for(int num:A) hash[num]++;
// 先统计每个数字的次数,然后按照不能重复的方法来计算
sort(A.begin(),A.end());
int n=A.size();
long long result=0;
for(int i=0;i<n-2;i++)
{
while(i>0&&A[i]==A[i-1]) i++;
int j=i+1;
int k=n-1;
while(j<k)
{
if(A[i]+A[j]+A[k]==target)
{
if(A[i]!=A[j]&&A[j]!=A[k]) //全部不同
result+=hash[A[i]]*hash[A[j]]*hash[A[k]];
else if(A[i]==A[j]&&A[j]==A[k]) //全部相同
result+=hash[A[i]]*(hash[A[j]]-1)*(hash[A[k]]-2)/6;
else if(A[i]==A[j]&&A[j]!=A[k]) //A[i]==A[j]
result+=hash[A[i]]*(hash[A[j]]-1)/2*hash[A[k]];
else if(A[i]!=A[j]&&A[j]==A[k]) //A[j]==A[k]
result+=hash[A[i]]*hash[A[j]]*(hash[A[k]]-1)/2;
j++;
k--;
while(j<k&&A[j]==A[j-1]) j++;
while(k>j&&A[k]==A[k+1]) k--;
}
else if(A[i]+A[j]+A[k]<target) j++;
else k--;
}
}
long long mod=pow(10,9)+7;
return result%mod;
}
};