3885 Count Special Triplets
3885 Count Special Triplets
Count Special Triplets 
You are given an integer array nums.
A special triplet is defined as a triplet of indices (i, j, k) such that:
1
2
3
0 <= i < j < k < n, where n = nums.length
nums[i] == nums[j] * 2
nums[k] == nums[j] * 2
Return the total number of special triplets in the array.
Since the answer may be large, return it modulo 109 + 7.
Example 1:
Input: nums = [6,3,6]
Output: 1
Explanation:
The only special triplet is (i, j, k) = (0, 1, 2), where:
1
2
3
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
Example 2:
Input: nums = [0,1,0,0]
Output: 1
Explanation:
The only special triplet is (i, j, k) = (0, 2, 3), where:
1
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
Example 3:
Input: nums = [8,4,2,8,4]
Output: 2
Explanation:
There are exactly two special triplets:
1
2
3
4
5
6
7
8
9
10
11
(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
Constraints:
1
2
3 <= n == nums.length <= 105
0 <= nums[i] <= 105
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
use std::collections::HashMap;
impl Solution {
pub fn special_triplets(nums: Vec<i32>) -> i32 {
const MOD: i64 = 1_000_000_007;
let mut pos: HashMap<i32, Vec<usize>> = HashMap::new();
for (i, &v) in nums.iter().enumerate() {
pos.entry(v).or_insert_with(Vec::new).push(i);
}
let upper_bound = |arr: &[usize], i: usize| -> (usize, usize) {
let (mut l, mut r) = (0, arr.len() - 1);
while l < r {
let mid = l + ((r - l + 1) >> 1);
if i >= arr[mid] {
l = mid;
} else {
r = mid - 1;
}
}
(l + 1, arr.len() - 1 - l)
};
let mut ans: i64 = 0;
for i in 1..nums.len() - 1 {
let target = nums[i] * 2;
if let Some(target_pos) = pos.get(&target) {
if target_pos.len() > 1 && target_pos[0] < i {
let (mut l, r) = upper_bound(target_pos, i);
if nums[i] == 0 {
l -= 1;
}
ans = (ans + l as i64 * r as i64) % MOD;
}
}
}
ans as i32
}
}
This post is licensed under CC BY 4.0 by the author.