存在重复元素 III
难度:
标签:
题目描述
English description is not available for the problem. Please switch to Chinese.
代码结果
运行时间: 29 ms, 内存: 18.4 MB
/*
* 思路:
* 1. 使用一个滑动窗口来保持最多k个元素。
* 2. 对于每个元素,检查窗口内是否有元素满足abs(nums[i] - nums[j]) <= t。
* 3. 使用Java Stream API来实现。
*/
import java.util.TreeSet;
import java.util.stream.IntStream;
public class SolutionStream {
public boolean containsNearbyAlmostDuplicate(int[] nums, int k, int t) {
if (nums == null || nums.length == 0 || k <= 0 || t < 0) {
return false;
}
TreeSet<Long> set = new TreeSet<>();
return IntStream.range(0, nums.length).anyMatch(i -> {
Long floor = set.floor((long) nums[i] + t);
Long ceiling = set.ceiling((long) nums[i] - t);
if ((floor != null && floor >= nums[i]) || (ceiling != null && ceiling <= nums[i])) {
return true;
}
set.add((long) nums[i]);
if (set.size() > k) {
set.remove((long) nums[i - k]);
}
return false;
});
}
}
解释
方法:
此题解采用了桶排序思想和滑动窗口的结合来解决问题。首先,定义一个桶的映射方法getId,该方法将每个数字映射到一个桶ID,其中每个桶的范围是大小为t+1的区间。然后,遍历数组,对于每个元素,检查其所在的桶及相邻桶是否存在满足条件的元素。如果数组索引i大于k,为了维护大小为k的窗口,将窗口外的元素从字典中移除(即删除过期的桶)。通过这种方式,我们保证了检查的元素总是在k距离内的元素,并通过桶的映射减少了比较的次数,从而提高了效率。
时间复杂度:
O(n)
空间复杂度:
O(k)
代码细节讲解
🦆
为什么在这个算法中选择使用桶排序的思路结合滑动窗口来解决问题?
▷🦆
桶的大小设置为`t + 1`是基于什么考虑?如何保证这种设置可以覆盖所有满足条件的情况?
▷🦆
在删除过期桶时,为什么要检查`i > k`而不是`i >= k`?这样处理的边界条件是否正确?
▷