单因数三元组
难度:
标签:
题目描述
代码结果
运行时间: 208 ms, 内存: 22.5 MB
/*
* LeetCode 2198: Number of Single-Factor Triplets using Java Streams
* Given an array of positive integers nums, find the number of triplets (i, j, k)
* such that 0 <= i < j < k < nums.length and nums[i] * nums[j] * nums[k] is a multiple of nums[i], nums[j], and nums[k].
*
* Approach:
* - Use Java Streams to generate a stream of indices, and for each combination of three indices, check the divisibility condition.
*/
import java.util.stream.IntStream;
public class SingleFactorTripletsStream {
public long countSingleFactorTriplets(int[] nums) {
int n = nums.length;
return IntStream.range(0, n - 2)
.boxed()
.flatMap(i -> IntStream.range(i + 1, n - 1)
.boxed()
.flatMap(j -> IntStream.range(j + 1, n)
.filter(k -> {
int product = nums[i] * nums[j] * nums[k];
return product % nums[i] == 0 && product % nums[j] == 0 && product % nums[k] == 0;
})
.mapToObj(k -> new int[]{i, j, k})
)
)
.count();
}
}
解释
方法:
本题解首先使用一个嵌套的循环构建一个字典 g,字典的键为 i,值为满足特定条件的二元组 (j, k) 的列表。特定条件是:i+j+k 除以 i 的余数为 0,除以 j 和 k 的余数不为 0。这表示 i 是 i+j+k 的唯一因子。在 Solution 类的 singleDivisorTriplet 方法中,首先初始化结果 res 为 0,并使用计数器 cnt 来记录 nums 中每个数字的出现次数。遍历 nums 中的唯一数字 a,对于每个 a,从字典 g 中找到所有符合条件的 (b, c)。如果 b 和 c 不相等,计算可能的三元组数量,并乘以 6(因为三元组 (a, b, c) 可以有 6 种不同的排列)。如果 b 和 c 相等,则需要特殊处理,使用组合数计算 b 选 2 的方式,并同样乘以 6。最终,返回计算出的结果 res。
时间复杂度:
O(n^2)
空间复杂度:
O(n^2)
代码细节讲解
🦆
为什么在检查条件时,除以i的余数需要为0,而除以j和k的余数不为0?这样的设计是基于什么考虑?
▷🦆
在构建字典g时,为何选择将k的循环起始于j(k从j开始)?这样做是为了避免什么问题?
▷🦆
在处理b和c相等的情况时,为什么需要特殊处理并使用组合数计算方式?这样做的原因是什么?
▷🦆
本题解中提到使用defaultdict(list)来构建字典g,使用这种数据结构有什么特殊的好处?
▷