Given an integer array arr[] and two integers indexDifference and valueDifference, find a pair of indices (i, j) such that:
- i != j
- abs(i - j) <= indexDifference
- abs(arr[i] - arr[j]) <= valueDifference
Return true if such a pair exists, false otherwise.
Example:
Input: arr = [1,2,3,1], indexDifference = 3, valueDifference = 0
Output: true
Explanation: We can choose (i, j) = (0, 3).We satisfy the three conditions:
- i != j --> 0 != 3
- abs(i - j) <= indexDifference --> abs(0 - 3) <= 3
- abs(arr[i] - arr[j]) <= valueDifference --> abs(1 - 1) <= 0
Input: arr = [1,5,9,1,5,9], indexDifference = 2, valueDifference = 3
Output: false
Explanation: After trying all the possible pairs (i, j), we cannot satisfy the three conditions, so we return false.
Approach:
The idea is to uses a sliding window approach with a multiset to efficiently find such a pair.
Main points:
- Sliding window: A window of size k+1 slides through the array. This window keeps track of the elements within a distance of k from the current element.
- Multiset: The window is implemented as a multiset, which stores the elements in sorted order. This allows for efficient retrieval of the closest elements to the current element.
- Checking for valid pairs: For each element in the window, the solution checks if there exists another element within the window that satisfies the given constraints. This is done by finding the upper and lower bounds of the current element in the multiset and comparing their absolute differences with the given t.
- Sliding the window: After checking for a valid pair, the window slides forward by removing the leftmost element and adding the next element from the array.
Steps-by-step approach:
- Create a multiset called window to store elements in sorted order.
- Initialize two indices, i and j, both starting at 0.
- Loop through the array using j as the index.
- For each element arr[j]:
- Find the upper bound of arr[j] in the window using upper_bound.
- If the upper bound exists and the absolute difference between it and arr[j] is less than or equal to t, return true.
- If the upper bound doesn't exist or the difference is greater than t, check the lower bound.
- Find the lower bound of arr[j] in the window using upper_bound (with a slight adjustment) and check the difference.
- If the lower bound exists and the absolute difference between it and arr[j] is less than or equal to t, return true.
- If no valid pair is found within the window, insert arr[j] into the window.
- If the window size exceeds k+1, remove the leftmost element (arr[i]) from the window and increment i.
- Increment j to move the window forward.
- If the loop completes without finding a valid pair, return false.
Below is the implementation of the above approach:
#include <bits/stdc++.h>
using namespace std;
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k,
int t)
{
// Create a multiset to store the window elements in
// sorted order
multiset<int> window;
// Initialize window size and indices
int n = nums.size();
int i = 0, j = 0;
// Iterate through the array
while (j < n) {
// Check if there exists a valid pair within the
// window
auto upper = window.upper_bound(
nums[j]); // Find the upper bound of nums[j] in
// the window
if ((upper != window.end() && *upper - nums[j] <= t)
|| // Check if the upper bound satisfies the
// constraints
(upper != window.begin()
&& nums[j] - *(--upper)
<= t)) { // Check if the lower bound
// satisfies the constraints
return true;
}
// Insert the current element into the window
window.insert(nums[j]);
// Maintain the window size
if (window.size() == k + 1) {
// Remove the leftmost element from the window
window.erase(nums[i]);
i++;
}
// Move the window forward
j++;
}
// No valid pair found
return false;
}
int main()
{
vector<int> nums = { 1, 2, 3, 1 };
int k = 3;
int t = 0;
bool result = containsNearbyAlmostDuplicate(nums, k, t);
if (result) {
cout << "There exists a pair of indices satisfying "
"the constraints."
<< endl;
}
else {
cout << "No such pair exists." << endl;
}
return 0;
}
import java.util.TreeSet;
class ContainsNearbyAlmostDuplicate {
public static boolean
containsNearbyAlmostDuplicate(int[] nums, int k, int t)
{
TreeSet<Long> window = new TreeSet<>();
int n = nums.length;
int i = 0, j = 0;
while (j < n) {
Long floor = window.floor((long)nums[j] + t);
Long ceil = window.ceiling((long)nums[j] - t);
if ((floor != null && floor >= nums[j])
|| (ceil != null && ceil <= nums[j])) {
return true;
}
window.add((long)nums[j]);
if (window.size() == k + 1) {
window.remove((long)nums[i]);
i++;
}
j++;
}
return false;
}
public static void main(String[] args)
{
int[] nums = { 1, 2, 3, 1 };
int k = 3;
int t = 0;
boolean result
= containsNearbyAlmostDuplicate(nums, k, t);
if (result) {
System.out.println(
"There exists a pair of indices satisfying the constraints.");
}
else {
System.out.println("No such pair exists.");
}
}
}
from sortedcontainers import SortedList
def containsNearbyAlmostDuplicate(nums, k, t):
# Create a sorted list to store the window elements in
window = SortedList()
# Initialize window size and indices
n = len(nums)
i, j = 0, 0
# Iterate through the array
while j < n:
# Check if there exists a valid pair within the window
# Find the upper bound of nums[j] in the window
upper = window.bisect_right(nums[j])
if (upper < len(window) and window[upper] - nums[j] <= t) or \
(upper > 0 and nums[j] - window[upper - 1] <= t):
# Check if the upper bound satisfies the constraints
return True
# Insert the current element into the window
window.add(nums[j])
# Maintain the window size
if len(window) == k + 1:
# Remove the leftmost element from the window
window.remove(nums[i])
i += 1
# Move the window forward
j += 1
# No valid pair found
return False
def main():
nums = [1, 2, 3, 1]
k = 3
t = 0
result = containsNearbyAlmostDuplicate(nums, k, t)
if result:
print("There exists a pair of indices satisfying the constraints.")
else:
print("No such pair exists.")
if __name__ == "__main__":
main()
function containsNearbyAlmostDuplicate(nums, k, t) {
const window = new Set();
let i = 0,
j = 0;
while (j < nums.length) {
let found = false;
for (let num of window) {
if (Math.abs(num - nums[j]) <= t) {
found = true;
break;
}
}
if (found) return true;
window.add(nums[j]);
if (window.size > k) {
window.delete(nums[i]);
i++;
}
j++;
}
return false;
}
// Main execution starts here
const nums = [1, 2, 3, 1];
const k = 3;
const t = 0;
const result = containsNearbyAlmostDuplicate(nums, k, t);
if (result) {
console.log("There exists a pair of indices satisfying the constraints.");
} else {
console.log("No such pair exists.");
}
Output
There exists a pair of indices satisfying the constraints.
Time complexity : O(N log k)
Auxiliary Space: O(k)