Skip to main content
Back to problems
#3488
Medium Algorithms

Closest equal element queries

Array Hash Table Binary Search
32.8% acceptance
Feb 25, 2026
120
10
You are given a circular array nums and an array queries. For each query i, you have to find the following: The minimum distance between the element at index queries[i] and any other index j in the circular array, where nums[j] == nums[queries[i]]. If no such index exists, the answer for that query should be -1. Return an array answer of the same size as queries, where answer[i] represents the result for query i.

Solution

Rust
Time O(n log n)
Space O(n)
LeetCode
solution.rs
impl Solution {
  pub fn solve_queries(nums: Vec<i32>, queries: Vec<i32>) -> Vec<i32> {
    use std::collections::HashMap;
    let n = nums.len();
    let mut positions: HashMap<i32, Vec<usize>> = HashMap::new();
    for (i, &v) in nums.iter().enumerate() {
      positions.entry(v).or_default().push(i);
    }
    queries.iter().map(|&q| {
      let q = q as usize;
      let v = nums[q];
      let pos = positions.get(&v).unwrap();
      if pos.len() < 2 { return -1; }
      // Find min circular distance from q to any other pos
      let idx = pos.partition_point(|&p| p < q);
      let mut min_dist = i32::MAX;
      // prev occurrence
      if idx > 0 {
        let d = q - pos[idx-1];
        min_dist = min_dist.min(d.min(n - d) as i32);
      }
      // next occurrence
      if idx < pos.len() - 1 || (idx > 0 && pos[idx] == q) {
        let next_idx = if pos[idx] == q { idx + 1 } else { idx };
        if next_idx < pos.len() {
          let d = pos[next_idx] - q;
          min_dist = min_dist.min(d.min(n - d) as i32);
        }
      }
      // wrap around: first and last in circular
      if pos.len() >= 2 {
        let first = pos[0]; let last = *pos.last().unwrap();
        if first != q {
          let d = if q > first { q - first } else { first - q };
          min_dist = min_dist.min(d.min(n - d) as i32);
        }
        if last != q {
          let d = if q > last { q - last } else { last - q };
          min_dist = min_dist.min(d.min(n - d) as i32);
        }
      }
      if min_dist == i32::MAX { -1 } else { min_dist }
    }).collect()
  }
}