目标
给你一个整数数组 nums。
特殊三元组 定义为满足以下条件的下标三元组 (i, j, k):
- 0 <= i < j < k < n,其中 n = nums.length
- nums[i] == nums[j] * 2
- nums[k] == nums[j] * 2
返回数组中 特殊三元组 的总数。
由于答案可能非常大,请返回结果对 10^9 + 7 取余数后的值。
示例 1:
输入: nums = [6,3,6]
输出: 1
解释:
唯一的特殊三元组是 (i, j, k) = (0, 1, 2),其中:
nums[0] = 6, nums[1] = 3, nums[2] = 6
nums[0] = nums[1] * 2 = 3 * 2 = 6
nums[2] = nums[1] * 2 = 3 * 2 = 6
示例 2:
输入: nums = [0,1,0,0]
输出: 1
解释:
唯一的特殊三元组是 (i, j, k) = (0, 2, 3),其中:
nums[0] = 0, nums[2] = 0, nums[3] = 0
nums[0] = nums[2] * 2 = 0 * 2 = 0
nums[3] = nums[2] * 2 = 0 * 2 = 0
示例 3:
输入: nums = [8,4,2,8,4]
输出: 2
解释:
共有两个特殊三元组:
(i, j, k) = (0, 1, 3)
nums[0] = 8, nums[1] = 4, nums[3] = 8
nums[0] = nums[1] * 2 = 4 * 2 = 8
nums[3] = nums[1] * 2 = 4 * 2 = 8
(i, j, k) = (1, 2, 4)
nums[1] = 4, nums[2] = 2, nums[4] = 4
nums[1] = nums[2] * 2 = 2 * 2 = 4
nums[4] = nums[2] * 2 = 2 * 2 = 4
说明:
- 3 <= n == nums.length <= 10^5
- 0 <= nums[i] <= 10^5
思路
找到数组 nums 的三元组 (i, j, k) 满足 nums[i] == nums[k] == 2 * nums[j],返回特殊三元组的个数。注意这里三元组是元素下标所以不会重复。
枚举右端点,如果为偶数,查找中间元素 nums[k]/2 作为右端点的二元组个数,该二元组 (i, j) 可以同时维护,找到左侧 i 的个数,满足 nums[i] == 2 * nums[j]。
代码
/**
* @date 2025-12-09 8:55
*/
public class SpecialTriplets3583 {
public int specialTriplets_v1(int[] nums) {
int n = nums.length;
int mod = 1000000007;
Map<Integer, Long> cnt = new HashMap<>();
Map<Integer, Long> binaryCnt = new HashMap<>();
long res = 0;
for (int i = 0; i < n; i++) {
if (nums[i] % 2 == 0) {
res += binaryCnt.getOrDefault(nums[i] / 2, 0L);
}
binaryCnt.merge(nums[i], cnt.getOrDefault(nums[i] * 2, 0L), Long::sum);
cnt.merge(nums[i], 1L, Long::sum);
}
return (int) (res % mod);
}
}
性能
