The minimum absolute difference of an array a
is defined as the minimum value of |a[i] - a[j]|
, where 0 <= i < j < a.length
and a[i] != a[j]
. If all elements of a
are the same, the minimum absolute difference is -1
.
[5,2,3,7,2]
is |2 - 3| = 1
. Note that it is not 0
because a[i]
and a[j]
must be different.You are given an integer array nums
and the array queries
where queries[i] = [li, ri]
. For each query i
, compute the minimum absolute difference of the subarray nums[li...ri]
containing the elements of nums
between the 0-based indices li
and ri
(inclusive).
Return an array ans
where ans[i]
is the answer to the ith
query.
A subarray is a contiguous sequence of elements in an array.
The value of |x|
is defined as:
x
if x >= 0
.-x
if x < 0
.Example 1:
Input: nums = [1,3,4,8], queries = [[0,1],[1,2],[2,3],[0,3]] Output: [2,1,4,1] Explanation: The queries are processed as follows: - queries[0] = [0,1]: The subarray is [1,3] and the minimum absolute difference is |1-3| = 2. - queries[1] = [1,2]: The subarray is [3,4] and the minimum absolute difference is |3-4| = 1. - queries[2] = [2,3]: The subarray is [4,8] and the minimum absolute difference is |4-8| = 4. - queries[3] = [0,3]: The subarray is [1,3,4,8] and the minimum absolute difference is |3-4| = 1.
Example 2:
Input: nums = [4,5,2,2,7,10], queries = [[2,3],[0,2],[0,5],[3,5]] Output: [-1,1,1,3] Explanation: The queries are processed as follows: - queries[0] = [2,3]: The subarray is [2,2] and the minimum absolute difference is -1 because all the elements are the same. - queries[1] = [0,2]: The subarray is [4,5,2] and the minimum absolute difference is |4-5| = 1. - queries[2] = [0,5]: The subarray is [4,5,2,2,7,10] and the minimum absolute difference is |4-5| = 1. - queries[3] = [3,5]: The subarray is [2,7,10] and the minimum absolute difference is |7-10| = 3.
Constraints:
2 <= nums.length <= 105
1 <= nums[i] <= 100
1 <= queries.length <= 2 * 104
0 <= li < ri < nums.length
When you get asked this question in a real-life environment, it will often be ambiguous (especially at FAANG). Make sure to ask these questions in that case:
The goal is to find the smallest difference between any two numbers within a specified range of numbers. The brute force method involves looking at every possible pair of numbers within that range and calculating the difference between them.
Here's how the algorithm would work step-by-step:
def min_abs_difference_queries_brute_force(numbers, queries):
results = []
for query in queries:
start_index = query[0]
end_index = query[1]
sub_array = numbers[start_index:end_index + 1]
minimum_absolute_differences = []
# Iterate through all possible pairs in the sub_array
for first_index in range(len(sub_array)):
minimum_difference_for_element = float('inf')
for second_index in range(first_index + 1, len(sub_array)):
difference = abs(sub_array[first_index] - sub_array[second_index])
# Store the smallest difference seen so far
minimum_difference_for_element = min(minimum_difference_for_element, difference)
#If min diff wasn't updated it's all identical numbers
if minimum_difference_for_element == float('inf'):
minimum_difference_for_element = -1
minimum_absolute_differences.append(minimum_difference_for_element)
#Find the minimum difference across the whole sub array
final_minimum_difference = float('inf')
for difference in minimum_absolute_differences:
# -1 values should be skipped
if difference != -1:
final_minimum_difference = min(final_minimum_difference, difference)
# If the final result was not updated return -1
if final_minimum_difference == float('inf'):
results.append(-1)
else:
results.append(final_minimum_difference)
return results
The most efficient way to solve this involves precomputing information to quickly answer each question. We track where each number appears and then use that to drastically speed up finding the smallest differences.
Here's how the algorithm would work step-by-step:
def min_difference_queries(numbers, queries):
number_positions = {}
for index, number in enumerate(numbers):
if number not in number_positions:
number_positions[number] = []
number_positions[number].append(index)
results = []
for start_index, end_index in queries:
numbers_in_range = []
for number, positions in number_positions.items():
for position in positions:
if start_index <= position <= end_index:
numbers_in_range.append(number)
break
# Sorting is crucial for finding the minimum adjacent difference.
numbers_in_range.sort()
if len(numbers_in_range) < 2:
results.append(-1)
continue
minimum_difference = float('inf')
for i in range(len(numbers_in_range) - 1):
# Iterate through and compare differences.
difference = abs(numbers_in_range[i] - numbers_in_range[i + 1])
minimum_difference = min(minimum_difference, difference)
# If no differences exist, return -1.
results.append(minimum_difference)
return results
Case | How to Handle |
---|---|
Empty nums array | Return an empty result list as no absolute differences can be computed. |
nums array with only one element | Return an empty result list because calculating the absolute difference requires at least two elements. |
Empty queries array | Return an empty result list because there are no queries to process. |
Large nums array and numerous queries | Consider efficient precomputation techniques like prefix sums or sorted lists to optimize query processing time. |
Queries where left > right | Handle such invalid queries, possibly by swapping 'left' and 'right' or returning a special error value. |
nums array contains duplicate values | The solution should correctly handle duplicates without incorrectly reporting smaller differences. |
nums array contains large integers (close to maximum integer value) | Be wary of potential integer overflow when calculating the absolute difference, and consider using larger data types (e.g., long) if necessary. |
All values in the sub array are same | The minimum absolute difference would be zero, and the solution should correctly return 0. |