You are given a 0-indexed integer array nums
and an integer x
.
Find the minimum absolute difference between two elements in the array that are at least x
indices apart.
In other words, find two indices i
and j
such that abs(i - j) >= x
and abs(nums[i] - nums[j])
is minimized.
Return* an integer denoting the minimum absolute difference between two elements that are at least* x
indices apart.
For example:
nums = [4,3,2,4], x = 2
should return 0
.
nums = [5,3,2,10,15], x = 1
should return 1
.
nums = [1,2,3,4], x = 3
should return 3
.
Constraints:
1 <= nums.length <= 10^5
1 <= nums[i] <= 10^9
0 <= x < nums.length
The most straightforward approach is to iterate through all possible pairs of elements in the array and check if their indices are at least x
apart. If they are, calculate the absolute difference between the elements and update the minimum difference found so far.
def min_abs_difference_naive(nums, x):
min_diff = float('inf')
n = len(nums)
for i in range(n):
for j in range(n):
if abs(i - j) >= x:
min_diff = min(min_diff, abs(nums[i] - nums[j]))
return min_diff
To optimize, we can use a sliding window approach combined with a sorted data structure (like a sorted list or a binary search tree) to efficiently find the minimum absolute difference. We maintain a window of elements that are at least x
indices behind the current element. For each element, we search for the closest elements in the sorted window to find the minimum absolute difference.
import bisect
def min_abs_difference_optimal(nums, x):
min_diff = float('inf')
n = len(nums)
sorted_window = []
for i in range(x, n):
sorted_window.append(nums[i-x])
sorted_window.sort()
# Find the element closest to nums[i] in the sorted window
left = 0
right = len(sorted_window)-1
while left <= right:
mid = (left+right)//2
min_diff = min(min_diff, abs(nums[i] - sorted_window[mid]))
if nums[i] > sorted_window[mid]:
left = mid+1
else:
right = mid-1
return min_diff
Naive Solution:
n
. Therefore, the run-time complexity is O(n^2).Optimal Solution:
sorted_window
. The sort()
is O(k log k) where k is the size of the sorted_window
. However, the max size of the sorted_window
is x
, so it's O(x log x). Therefore, the overall runtime is O(n * x log x)Naive Solution:
Optimal Solution:
sorted_window
which can have up to x
elements in it. Therefore, the space complexity is O(x).nums
is empty, the function should return float('inf')
or raise an exception, depending on the desired behavior.x
is 0, then any two elements can be compared, and we should return the minimum absolute difference among all pairs.x
is greater than or equal to the length of nums
, then no two elements can satisfy the distance condition, and the function should return float('inf')
(or an error).Here's how we can handle these edge cases in the optimal solution:
import bisect
def min_abs_difference_optimal(nums, x):
if not nums:
return float('inf')
n = len(nums)
if x >= n:
return float('inf')
min_diff = float('inf')
sorted_window = []
for i in range(x, n):
sorted_window.append(nums[i-x])
sorted_window.sort()
# Find the element closest to nums[i] in the sorted window
left = 0
right = len(sorted_window)-1
while left <= right:
mid = (left+right)//2
min_diff = min(min_diff, abs(nums[i] - sorted_window[mid]))
if nums[i] > sorted_window[mid]:
left = mid+1
else:
right = mid-1
return min_diff