三数之和的多种可能
难度:
标签:
题目描述
代码结果
运行时间: 38 ms, 内存: 16.1 MB
/*
* Problem: Given an integer array arr and an integer target, return the number of tuples (i, j, k)
* such that i < j < k and arr[i] + arr[j] + arr[k] == target.
* The result should be returned modulo 10^9 + 7.
*/
import java.util.*;
import java.util.stream.Collectors;
public class SolutionStream {
public int threeSumMulti(int[] arr, int target) {
final int MOD = 1000000007;
Map<Integer, Long> countMap = Arrays.stream(arr)
.boxed()
.collect(Collectors.groupingBy(e -> e, Collectors.counting()));
long result = 0;
List<Integer> keys = new ArrayList<>(countMap.keySet());
for (int i = 0; i < keys.size(); i++) {
for (int j = i; j < keys.size(); j++) {
int x = keys.get(i);
int y = keys.get(j);
int z = target - x - y;
if (countMap.containsKey(z)) {
long countX = countMap.get(x);
long countY = countMap.get(y);
long countZ = countMap.get(z);
if (x == y && y == z) {
result += countX * (countX - 1) * (countX - 2) / 6;
} else if (x == y && y != z) {
result += countX * (countX - 1) / 2 * countZ;
} else if (x < y && y < z) {
result += countX * countY * countZ;
}
result %= MOD;
}
}
}
return (int) result;
}
}
解释
方法:
此题解采用哈希表和组合计数的方法来解决三数之和的问题。首先,使用Counter统计数组中每个数字的出现次数。然后,对哈希表的键进行排序,以便在后续的双重循环中按序处理。在双重循环中,对于每一对数字(i, j),计算第三个数字k为target-i-j。如果i,j和k满足条件i <= j <= k,则根据i,j和k的关系(是否相等)使用组合公式计算满足条件的三元组数量,并对结果进行累加。特别注意,只有当k也在哈希表中时,才会添加到答案中。最终,返回累加结果对1e9+7取模的值。
时间复杂度:
O(1)
空间复杂度:
O(1)
代码细节讲解
🦆
在题解中提到的组合公式计算,具体是如何实现的?例如,当 i, j, k 相等时,为什么使用 comb(cnt[i], 3)?
▷🦆
为何在双重循环中只有当 k >= j 时才考虑,这种筛选条件是如何帮助减少不必要计算的?
▷🦆
在哈希表的键排序后,对于每一对数字 (i, j),计算 k = target - i - j 时,如果 k 不在哈希表中,这种情况如何处理?是否直接跳过该组合?
▷🦆
最终结果需要对 10^9 + 7 取模,这一步骤在计算中有什么特别的意义或必要性?
▷