You are given an integer array nums
and two integers indexDiff
and valueDiff
.
Find a pair of indices (i, j)
such that:
i != j
,abs(i - j) <= indexDiff
.abs(nums[i] - nums[j]) <= valueDiff
, andReturn true
if such pair exists or false
otherwise.
Example 1:
nums = [1,2,3,1], indexDiff = 3, valueDiff = 0
Output: true
Explanation: We can choose (i, j) = (0, 3). We satisfy the three conditions: i != j --> 0 != 3 abs(i - j) <= indexDiff --> abs(0 - 3) <= 3 abs(nums[i] - nums[j]) <= valueDiff --> abs(1 - 1) <= 0
Example 2:
nums = [1,5,9,1,5,9], indexDiff = 2, valueDiff = 3
Output: false
Explanation: After trying all the possible pairs (i, j), we cannot satisfy the three conditions, so we return false
.
Can you implement a function to solve this problem efficiently?
The naive solution is to iterate through all possible pairs of indices (i, j)
and check if they satisfy the given conditions. This approach has a time complexity of O(n^2), where n is the length of the input array nums
.
def contains_nearby_almost_duplicate_naive(nums, indexDiff, valueDiff):
n = len(nums)
for i in range(n):
for j in range(i + 1, n):
if abs(i - j) <= indexDiff and abs(nums[i] - nums[j]) <= valueDiff:
return True
return False
Big O Runtime: O(n^2)
Big O Space: O(1)
An optimal solution can be achieved using a sliding window and a sorted set (e.g., a TreeSet in Java or SortedList in Python). The idea is to maintain a window of size indexDiff
and for each element nums[i]
, check if there exists an element in the window that satisfies the valueDiff
condition.
from sortedcontainers import SortedList
def contains_nearby_almost_duplicate(nums, indexDiff, valueDiff):
window = SortedList()
for i, num in enumerate(nums):
if i > indexDiff:
window.remove(nums[i - indexDiff - 1])
# Find the smallest element in the window that is >= num - valueDiff
idx = window.bisect_left(num - valueDiff)
if idx < len(window) and window[idx] <= num + valueDiff:
return True
window.add(num)
return False
Explanation:
SortedList
called window
to maintain the elements within the index difference.nums
, we first check if the current index i
is greater than indexDiff
. If so, we remove the element that is no longer within the window (i.e., nums[i - indexDiff - 1]
).bisect_left
to find the index of the smallest element in the window
that is greater than or equal to num - valueDiff
. This allows us to efficiently check if any element in the window
is within the valueDiff
range of the current number.True
.num
to the window
.Big O Runtime: O(n log k), where n is the length of nums and k is the indexDiff
Big O Space: O(k), where k is the indexDiff
false
if the input array is empty.indexDiff
is greater than or equal to the length of the array: The sliding window will cover the entire array.valueDiff
is 0: The algorithm should check for duplicate elements within the indexDiff
range.valueDiff
= 0, indexDiff
> 0, should return true.