Contains Duplicate 3 - within k distance and t difference
Problem
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.
OR
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, and
Return true if such pair exists or false otherwise.
Examples
Example 1:
Input: 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:
Input: 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.
Solution
Method 1 - Using TreeSet and Sliding Window
To solve the problem, we can use a sliding window approach and a data structure that allows efficient insertion, deletion, and lookup. A TreeSet provides these capabilities with logarithmic time complexity for each operation, making it a good choice for this problem.
Approach
- Use a
TreeSetto maintain a sliding window ofindexDifforksize. - For each element in
nums:- Use
TreeSet.floor()andTreeSet.ceiling()to find the nearest elements within thevalueDiffort. - If any such element is found, return
true. - Maintain the sliding window by adding the current element to the set and removing the element that is
indexDifforkpositions before the current index.
- Use
Lets see what floor and ceiling mean.
floor(x) = Largest element <= to the x.
ceiling(x) = Smallest element >= to the x.
So, if TreeSet has following elements:
set = [1, 2, 4, 5]
Then, here are floor and ceiling of 3:
floor(3) = 2
ceiling(3) = 4
Code
Java
public class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || nums.length < 2 || k < 1 || t < 0) {
return false;
}
// TreeSet to maintain the sliding window of `k` size
TreeSet<Integer> set = new TreeSet<>();
for (int i = 0; i < nums.length; i++) {
int num = nums[i];
// Check the floor within the t range
Integer floor = set.floor(num);
if (floor != null && Math.abs(num - floor) <= t) {
return true;
}
// Check the ceiling within the t range
Integer ceiling = set.ceiling(num);
if (ceiling != null && Math.abs(ceiling - num) <= t) {
return true;
}
set.add(num);
// Maintain the sliding window by removing the element that is `k` positions before the current index
if (i >= k) {
set.remove(nums[i - k]);
}
}
return false;
}
}
Complexity
- ⏰ Time complexity:
O(n log k)wherenis the length of the array andkisindexDiff. Because, we check each numbers floors and ceils, then add it to set, which takeslog k, as we only storekelements in Treeset, and we do it for n elements, henceO(n log k) - 🧺 Space complexity:
O(k)