题解地址:https://leetcode-cn.com/problems/contains-duplicate-iii/solution/hua-dong-chuang-kou-er-fen-sou-suo-shu-zhao-shang-/
给定一个整数数组,判断数组中是否有两个不同的索引
i
和j
,使得nums [i]
和nums [j]
的差的绝对值最大为t
,并且i
和j
之间的差的绝对值最大为ķ
。
示例 1:
输入: nums = [1, 2, 3, 1], k = 3, t = 0
输出: true
示例 2:
输入:nums = [1, 0, 1, 1], k = 1, t = 2
输出:true
示例 3:
输入:nums = [1, 5, 9, 1, 5, 9], k = 2, t = 3
输出:false
枚举所有长度小于等于 k + 1
的“下标对()
”,只要发现 nums[i] - nums[j]
的绝对值小于 t
,就返回 true
。
Java 代码:
public class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
int len = nums.length;
long a;
long b;
for (int i = 0; i < len; i++) {
for (int j = i + 1; j < len && j <= i + k; j++) {
a = nums[i];
b = nums[j];
if (Math.abs(a - b) <= t) {
return true;
}
}
}
return false;
}
}
复杂度分析:
题目意思翻译一下:在数组 nums[i]
中,在任意区间 [i, i + k]
里是否存在两个数的绝对值小于等于 t
,即 ∣ n u m s [ i ] − n u m s [ j ] ∣ < = t |nums[i] - nums[j] | <= t ∣nums[i]−nums[j]∣<=t ,
等价于 n u m s [ i ] − n u m s [ j ] < = t nums[i] - nums[j] <= t nums[i]−nums[j]<=t 并且 n u m s [ i ] − n u m s [ j ] > = − t nums[i] - nums[j] >= -t nums[i]−nums[j]>=−t,
即 n u m s [ i ] < = t + n u m s [ j ] nums[i] <= t + nums[j] nums[i]<=t+nums[j] 并且 n u m s [ i ] > = n u m s [ j ] − t nums[i] >= nums[j] - t nums[i]>=nums[j]−t。
Java 代码:
import java.util.TreeSet;
public class Solution {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
// 滑动窗口结合查找表,此时滑动窗口即为查找表本身(控制查找表的大小即可控制窗口大小)
TreeSet<Long> set = new TreeSet<>();
for (int i = 0; i < nums.length; i++) {
// 边添加边查找
// 查找表中是否有大于等于 nums[i] - t 且小于等于 nums[i] + t 的值
Long ceiling = set.ceiling((long) nums[i] - (long) t);
if (ceiling != null && ceiling <= ((long) nums[i] + (long) t)) {
return true;
}
// 添加后,控制查找表(窗口)大小,移除窗口最左边元素
set.add((long) nums[i]);
if (set.size() == k + 1) {
set.remove((long) nums[i - k]);
}
}
return false;
}
}
另一种写法:在一开始就把多余的元素删除。
Java 代码:
import java.util.TreeSet;
public class Solution11 {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
int len = nums.length;
// 特判
if (len == 0 || k <= 0 || t < 0) {
return false;
}
TreeSet<Long> set = new TreeSet<>();
for (int i = 0; i < len; i++) {
if (i > k) {
set.remove((long) nums[i - k - 1]);
}
Long ceiling = set.ceiling((long) nums[i] - (long) t);
if (ceiling != null && ceiling <= (long) nums[i] + (long) t) {
return true;
}
set.add((long) nums[i]);
}
return false;
}
}
复杂度分析: