题目
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.
Example 1:
Input: nums = [1,2,3,1], k = 3, t = 0
Output: true
Example 2:
Input: nums = [1,0,1,1], k = 1, t = 2
Output: true
Example 3:
Input: nums = [1,5,9,1,5,9], k = 2, t = 3
Output: false
解法思路(一)
- 题目其实限定了 2 个条件:
- 在一定范围内找;
- 找和标定元素的绝对差(absolute difference)小于等于 t 的;
- 在游标
i
前进的过程中,不满足条件的元素就被装入查找表; - 不满足条件的元素是:
nums[i]
在其后的窗口中,没有找到与nums[i]
之间的绝对差小于等于t
的,那么nums[i]
就成了不满足条件的元素,要进入滑动窗口; -
查找表中能装的元素最多为
k + 1
个,查找表作为滑动窗口的容器,当其中的元素个数到达k + 1
时要把滑动窗口的长度维护在k
; - 与
nums[i]
之间的绝对差等于t
的元素分别表示为:nums[i] - t
,nums[i] + t
; - 在滑动窗口(查找表)中找到大于等于
nums[i] - t
的且小于等于nums[i] + t
的元素,就成功了,否则,如果游标i
都走完了整个数组没有满足这个条件的,则失败了; - 由于查找表中的元素涉及到大小的比较,所以 HashSet 就不能用了,要用 TreeSet 了,伴随而来的代价查找的时间复杂度从 O(1) 降为 O(logK);
- 在哈希表中找大于等于某个值用方法:
E ceiling(E e)
;
解法实现(一)
时间复杂度
- O(NlogK);
空间复杂度
- O(K);
关键字
查找表
TreeSet
整型溢出
绝对差
ceiling
实现细节
- 如果
num[i]
已经是整型的最大值了,如果给出的绝对差也是整型的最大值,那么计算num[i]
右边的元素nums[i] + t
就会发生整型越界,这时,要把参加运算的所有整型强转成 long 型,故 TreeSet 中存储泛型要定义成 Long;
package leetcode._220;
import java.util.TreeSet;
public class Solution220_1 {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
TreeSet<Long> windowK = new TreeSet<>();
for (int i = 0; i < nums.length; i++) {
if (windowK.ceiling((long)nums[i] - (long)t) != null
&& windowK.ceiling((long)nums[i] - (long)t) <= (long)nums[i] + (long)t) {
return true;
}
windowK.add((long)nums[i]);
if (windowK.size() == k + 1) {
windowK.remove((long)nums[i - k]);
}
}
return false;
}
}