LeetCode Solutions
220. Contains Duplicate III
Time: $O(n\log k)$ Space: $O(k)$
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
set<long> window;
for (int i = 0; i < nums.size(); ++i) {
const auto it = window.lower_bound(static_cast<long>(nums[i]) - t);
if (it != cend(window) && *it - nums[i] <= t)
return true;
window.insert(nums[i]);
if (i >= k)
window.erase(nums[i - k]);
}
return false;
}
};
class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
TreeSet<Long> set = new TreeSet<>();
for (int i = 0; i < nums.length; ++i) {
final long num = (long) nums[i];
final Long ceiling = set.ceiling(num); // The smallest num >= nums[i]
if (ceiling != null && ceiling - num <= t)
return true;
final Long floor = set.floor(num); // The largest num <= nums[i]
if (floor != null && num - floor <= t)
return true;
set.add(num);
if (i >= k)
set.remove((long) nums[i - k]);
}
return false;
}
}
class Solution {
public:
bool containsNearbyAlmostDuplicate(vector<int>& nums, int k, int t) {
if (nums.empty() || k <= 0 || t < 0)
return false;
const long min = *min_element(begin(nums), end(nums));
const long diff = t + 1L; // In case of t = 0
// Use long because corner case INT_MAX - (-1) will overflow
unordered_map<long, long> bucket;
for (int i = 0; i < nums.size(); ++i) {
const long num = nums[i];
const long key = getKey(num, min, diff);
if (bucket.count(key)) // Current bucket
return true;
if (bucket.count(key - 1) &&
num - bucket[key - 1] < diff) // Left adjacent bucket
return true;
if (bucket.count(key + 1) &&
bucket[key + 1] - num < diff) // Right adjacent bucket
return true;
bucket[key] = num;
if (i >= k)
bucket.erase(getKey(nums[i - k], min, diff));
}
return false;
}
private:
int getKey(long num, long min, long diff) {
return (num - min) / diff;
}
};