/// Finds the minimum distance between two target values in a slice.
///
/// Returns:
/// - `Some(distance)` if a valid pair exists.
/// - `None` if no valid pair exists.
///
/// Time Complexity: O(n)
/// Space Complexity: O(1)
fn find_minimum_distance(
numbers: &[i32],
target1: i32,
target2: i32,
) -> Option<usize> {
// Special case: both targets are the same value.
if target1 == target2 {
return find_minimum_distance_between_duplicates(
numbers,
target1,
);
}
let mut last_seen_index: Option<usize> = None;
let mut min_distance: Option<usize> = None;
for (current_index, ¤t_value) in numbers.iter().enumerate() {
// Ignore values that are not targets.
if current_value != target1 && current_value != target2 {
continue;
}
/*
* If we previously saw one target value and the current
* value is the other target value, update the minimum distance.
*/
if let Some(previous_index) = last_seen_index {
if current_value != numbers[previous_index] {
let distance = current_index - previous_index;
min_distance = Some(
min_distance.map_or(
distance,
|current_min| current_min.min(distance),
),
);
}
}
// Remember the most recent occurrence.
last_seen_index = Some(current_index);
}
min_distance
}
/// Finds the minimum distance between consecutive occurrences
/// of the same value.
fn find_minimum_distance_between_duplicates(
numbers: &[i32],
target: i32,
) -> Option<usize> {
let mut previous_index: Option<usize> = None;
let mut min_distance: Option<usize> = None;
for (current_index, ¤t_value) in numbers.iter().enumerate() {
if current_value != target {
continue;
}
if let Some(index) = previous_index {
let distance = current_index - index;
min_distance = Some(
min_distance.map_or(
distance,
|current_min| current_min.min(distance),
),
);
}
previous_index = Some(current_index);
}
min_distance
}
fn main() {
let numbers = vec![2, 3, 7, 3, 3, 4, 8, 8, 8, 11, 9, 1, 3];
match find_minimum_distance(&numbers, 3, 8) {
Some(distance) => {
println!(
"Minimum distance between 3 and 8: {}",
distance
);
}
None => {
println!("No valid pair found.");
}
}
}
/*
run:
Minimum distance between 3 and 8: 2
*//