Given an array of integers arr
, your task is to find all pairs of elements with the minimum absolute difference between any two elements in the array. Return a list of pairs (each pair is a list of two integers) sorted in ascending order.
[a, b]
should satisfy a < b
.
2 <= arr.length <= 10^5
-10^6 <= arr[i] <= 10^6
Example:
Input: arr = [4,2,1,3]
Output: [[1,2],[2,3],[3,4]]
The naive way to solve this problem would be to check every possible pair of elements in the array, compute their absolute differences, and find the minimum. However, this approach is inefficient for large arrays because it requires checking all possible pairs, resulting in a time complexity of O(n²).
To optimize, we can take advantage of the fact that the smallest absolute difference between any two numbers in a list occurs between two adjacent numbers in a sorted array. Imagine lining up the numbers in order; the closest numbers will be next to each other. This means we only need to compare each number to its neighbor after sorting, rather than every possible pair.
By recognizing this property, we shift from a brute-force approach to a much more efficient one, leveraging sorting and single-pass comparison.
Let's break down the optimized solution step by step:
arr
in ascending order.
This approach is efficient because sorting is O(n log n), and the single pass through the array is O(n).
Let's use the sample input: arr = [4, 2, 1, 3]
[1, 2, 3, 4]
[[1, 2], [2, 3], [3, 4]]
At each step, we only need to look at adjacent elements, ensuring both efficiency and correctness.
class Solution:
def minimumAbsDifference(self, arr):
arr.sort()
min_diff = float('inf')
result = []
for i in range(1, len(arr)):
diff = arr[i] - arr[i - 1]
if diff < min_diff:
min_diff = diff
result = [[arr[i - 1], arr[i]]]
elif diff == min_diff:
result.append([arr[i - 1], arr[i]])
return result
class Solution {
public:
vector<vector<int>> minimumAbsDifference(vector<int>& arr) {
sort(arr.begin(), arr.end());
int minDiff = INT_MAX;
vector<vector<int>> result;
for (int i = 1; i < arr.size(); ++i) {
int diff = arr[i] - arr[i - 1];
if (diff < minDiff) {
minDiff = diff;
result.clear();
result.push_back({arr[i - 1], arr[i]});
} else if (diff == minDiff) {
result.push_back({arr[i - 1], arr[i]});
}
}
return result;
}
};
class Solution {
public List<List<Integer>> minimumAbsDifference(int[] arr) {
Arrays.sort(arr);
int minDiff = Integer.MAX_VALUE;
List<List<Integer>> result = new ArrayList<>();
for (int i = 1; i < arr.length; i++) {
int diff = arr[i] - arr[i - 1];
if (diff < minDiff) {
minDiff = diff;
result.clear();
result.add(Arrays.asList(arr[i - 1], arr[i]));
} else if (diff == minDiff) {
result.add(Arrays.asList(arr[i - 1], arr[i]));
}
}
return result;
}
}
var minimumAbsDifference = function(arr) {
arr.sort((a, b) => a - b);
let minDiff = Infinity;
let result = [];
for (let i = 1; i < arr.length; i++) {
let diff = arr[i] - arr[i - 1];
if (diff < minDiff) {
minDiff = diff;
result = [[arr[i - 1], arr[i]]];
} else if (diff === minDiff) {
result.push([arr[i - 1], arr[i]]);
}
}
return result;
};
Brute-force approach:
- Time Complexity: O(n²), because it checks every possible pair.
- Space Complexity: O(n), for storing the result pairs.
Optimized approach (sorting + single pass):
The optimized approach is much more efficient and suitable for large input sizes.
By recognizing that the minimum absolute difference in an array occurs between adjacent elements in the sorted order, we can reduce the problem to sorting and a single pass comparison. This strategy is both elegant and efficient, leveraging the properties of sorted arrays to avoid unnecessary computations. The key insight is to sort first, then only check adjacent pairs, making the solution both simple and powerful.