Skip to main content
Back to problems
#3583
Medium Algorithms

Count special triplets

Array Hash Table Counting
47.1% acceptance
Feb 25, 2026
549
23
Count special triplets: i < j < k such that nums[i] = 2*nums[j] AND nums[k] = 2*nums[j].

Solution

Rust
Time O(n)
Space O(n)
LeetCode
solution.rs
impl Solution {
  pub fn special_triplets(nums: Vec<i32>) -> i32 {
    const MOD: i64 = 1_000_000_007;
    let n = nums.len();
    // For each j (middle), count left[j] = #{i<j: nums[i] == 2*nums[j]}
    //                       right[j] = #{k>j: nums[k] == 2*nums[j]}
    // answer = sum of left[j]*right[j] for all j mod MOD

    // Step 1: compute right counts using a frequency map (scan right to left)
    let mut right_freq: std::collections::HashMap<i32, i64> = std::collections::HashMap::new();
    let mut right_counts = vec![0i64; n];
    // scan right to left, for index j, right_count[j] = freq of 2*nums[j] in j+1..n-1
    for j in (0..n).rev() {
      let target = 2 * nums[j];
      right_counts[j] = *right_freq.get(&target).unwrap_or(&0);
      *right_freq.entry(nums[j]).or_insert(0) += 1;
    }

    // Step 2: scan left to right, maintain left_freq
    let mut left_freq: std::collections::HashMap<i32, i64> = std::collections::HashMap::new();
    let mut ans: i64 = 0;
    for j in 0..n {
      let target = 2 * nums[j];
      let lc = *left_freq.get(&target).unwrap_or(&0);
      ans = (ans + lc * right_counts[j]) % MOD;
      *left_freq.entry(nums[j]).or_insert(0) += 1;
    }

    ans as i32
  }
}