问题:
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the absolute difference between nums[i] and nums[j] is at most t and the absolute difference between i and j is at most k.
解决:
给定一个整数数组,判断其中是否存在两个不同的下标i
和j
,满足:| nums[i] - nums[j] | <= t
且下标:| i - j | <= k
。
① 滑动窗口+TreeSet,TreeSet数据结构(Java)使用红黑树实现,是平衡二叉树的一种。
class Solution {//58ms
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || nums.length < 2 || k < 0 || t < 0) return false;
TreeSet<Long> set = new TreeSet<>();
for (int i = 0;i < nums.length;i ++){
long cur = (long) nums[i];
long leftBoundary = (long) cur - t;
long rightBoundary = (long) cur + t + 1;
SortedSet<Long> sub = set.subSet(leftBoundary,rightBoundary);
if (sub.size() > 0){
return true;
}
set.add(cur);
if (i >= k){
set.remove((long) nums[i - k]);
}
}
return false;
}
}
② 进化版。
使用TreeSet的两个方法:
1. floor()方法返set中≤给定元素的最大元素;如果不存在这样的元素,则返回 null。
2. ceiling()方法返回set中≥给定元素的最小元素;如果不存在这样的元素,则返回 null。
class Solution {//61ms
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || nums.length < 2 || k < 0 || t < 0) return false;
TreeSet<Integer> set = new TreeSet<>();
for (int i = 0;i < nums.length;i ++){
int cur = nums[i];
if ((set.floor(cur) != null && cur <= set.floor(cur) + t) ||
(set.ceiling(cur) != null && cur >= set.ceiling(cur) - t)){
return true;
}
set.add(cur);
if (i >= k){
set.remove(nums[i - k]);
}
}
return false;
}
}
③ 在discuss中看到的。。。
class Solution { //3ms
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || nums.length < 2 || k < 1 || t < 0) return false;
int left = 0;
int right = 1;
while(left < nums.length - 1 && right < nums.length){
if ( Math.abs((long) nums[right] - nums[left]) <= t){
return true;
}
if (right - left == k || right == nums.length - 1){
left ++;
if (t != 0){
right = left + 1;
}
}else{
right ++;
}
}
return false;
}
}