How to find the minimum distance between two numbers in a vector with Rust

1 Answer

0 votes
/// 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, &current_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, &current_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

*//

 



answered Oct 21 by avibootz
...