Watch 8 video solutions for Minimum Absolute Difference Queries, a medium level problem involving Array, Hash Table. This walkthrough by Fraz has 6,774 views views. Want to try solving it yourself? Practice on FleetCode or read the detailed text solution.
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 <= 1051 <= nums[i] <= 1001 <= queries.length <= 2 * 1040 <= li < ri < nums.lengthProblem Overview: You are given an integer nums and multiple queries [l, r]. For each query, consider the subarray nums[l..r] and return the minimum absolute difference between any two distinct values. If the subarray contains only one unique value, return -1. The challenge is answering many range queries efficiently.
Approach 1: Brute Force with Sorting (O(q * k log k) time, O(k) space)
For each query, extract the subarray nums[l..r], sort it, then compute the minimum difference between adjacent elements. Sorting works because the smallest absolute difference must appear between neighbors in sorted order. If the subarray length is k, sorting costs O(k log k) and scanning adjacent pairs costs O(k). This approach is straightforward but slow when there are many queries or large ranges.
Approach 2: Sort and Compare Adjacent Elements (O(q * k log k) time, O(k) space)
This method applies the same key observation: the minimum absolute difference must occur between adjacent elements after sorting. For each query, copy the range into a temporary array, sort it, then iterate once to compute the minimum gap. The algorithm is easy to implement in languages like C, C++, Java, Python, C#, and JavaScript. However, repeatedly sorting overlapping ranges leads to unnecessary work, making it inefficient for large datasets.
Approach 3: Frequency and Preprocessing (O(n * 100 + q * 100) time, O(n * 100) space)
The constraint that values lie between 1 and 100 enables a much faster approach. Build a prefix frequency table where prefix[i][v] stores how many times value v appears in the first i elements. For a query [l, r], determine which numbers exist in the range by subtracting prefix counts. Then scan values 1..100 and track the previous seen value to compute the minimum difference. Each query only checks 100 possible numbers, so it runs in constant time relative to input size.
This technique uses range counting and preprocessing, common in array query problems. The prefix table allows constant-time checks for whether a value exists in a range, avoiding repeated scans of the original array. A small fixed domain makes the algorithm extremely efficient.
Optimized Approach with Precomputation: The prefix-frequency strategy is the intended optimal solution. Precompute counts once, then process each query by iterating through the possible value range and calculating differences between consecutive present numbers. Time complexity becomes O(n * 100 + q * 100) and space complexity O(n * 100). This pattern appears frequently in range-query problems involving small integer domains and can be combined with structures like hash tables or prefix arrays.
Recommended for interviews: Start by explaining the sorting-based brute force to show the core observation about adjacent differences. Then transition to the prefix-frequency optimization. Interviewers expect the preprocessing solution because it reduces each query to scanning a fixed value range instead of repeatedly sorting subarrays.
| Approach | Time | Space | When to Use |
|---|---|---|---|
| Brute Force with Sorting | O(q * k log k) | O(k) | Small arrays or when the number of queries is very low |
| Sort and Compare Adjacent Elements | O(q * k log k) | O(k) | Simple implementation when optimization is not required |
| Frequency and Preprocessing (Prefix Counts) | O(n * 100 + q * 100) | O(n * 100) | Best choice when there are many queries and values are within a small fixed range |