# Finds the minimum distance between two values in an array.
#
# @param numbers [Array<Integer>] The array to search.
# @param target1 [Integer] The first target value.
# @param target2 [Integer] The second target value.
#
# @return [Integer]
# The minimum distance between the target values,
# or -1 if no valid pair exists.
#
# Time Complexity: O(n)
# Space Complexity: O(1)
def find_minimum_distance(numbers, target1, target2)
raise ArgumentError, "numbers cannot be nil" if numbers.nil?
# Special case: both targets are the same value.
return find_minimum_distance_between_duplicates(numbers, target1) if target1 == target2
last_seen_index = nil
min_distance = nil
numbers.each_with_index do |current_value, current_index|
# Ignore values that are not targets.
next unless current_value == target1 || current_value == target2
# If we previously saw the other target value,
# update the minimum distance.
unless last_seen_index.nil?
if current_value != numbers[last_seen_index]
distance = current_index - last_seen_index
min_distance =
min_distance.nil? ? distance : [min_distance, distance].min
end
end
# Remember the most recent occurrence.
last_seen_index = current_index
end
min_distance || -1
end
# Finds the minimum distance between consecutive occurrences
# of the same value.
#
# @param numbers [Array<Integer>] The array to search.
# @param target [Integer] The target value.
#
# @return [Integer]
# The minimum distance between occurrences,
# or -1 if fewer than two occurrences exist.
def find_minimum_distance_between_duplicates(numbers, target)
previous_index = nil
min_distance = nil
numbers.each_with_index do |value, index|
next unless value == target
unless previous_index.nil? distance = index - previous_index
min_distance = min_distance.nil? ? distance : [min_distance, distance].min
end
previous_index = index
end
min_distance || -1
end
# Example usage
numbers = [2, 3, 7, 3, 3, 4, 8, 8, 8, 11, 9, 1, 3]
result = find_minimum_distance(numbers, 3, 8)
if result >= 0
puts "Minimum distance between 3 and 8: #{result}"
else
puts "No valid pair found."
end
# run:
#
# Minimum distance between 3 and 8: 2
#