leetcode
leetcode 2951 ~ 3000
存在重复元素 III

存在重复元素 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)

代码细节讲解

🦆
为什么在这个算法中选择使用桶排序的思路结合滑动窗口来解决问题?
桶排序的思路被用于此算法中是为了高效地处理和维护元素与其索引之间的关系,同时确保可以快速比较元素差的大小是否满足条件。结合滑动窗口的方法,可以保证我们只在一个固定大小为k的窗口内进行比较,从而满足条件`abs(i - j) <= k`。这种结合使用减少了不必要的比较,提高了算法的效率,并且便于处理和更新元素。将元素分配到桶中,使得每个桶内的元素值之间的差异很小(不超过t),这样可以快速定位并判断是否有符合条件的元素对。
🦆
桶的大小设置为`t + 1`是基于什么考虑?如何保证这种设置可以覆盖所有满足条件的情况?
桶的大小设置为`t + 1`是为了确保桶内的任何两个元素的差值绝对不会大于`t`。这样的设置可以保证如果两个元素在同一个桶内,它们的差值必然满足`abs(nums[i] - nums[j]) <= t`。此外,这种设置也便于处理元素可能跨桶比较的情况,只需要检查相邻的桶即可(当前桶及左右各一个桶),这样可以保证覆盖所有可能的满足条件的元素对,因为即使两个元素处在不同桶,只要它们的差值小于等于t,它们也会被检查到。
🦆
在删除过期桶时,为什么要检查`i > k`而不是`i >= k`?这样处理的边界条件是否正确?
检查`i > k`而不是`i >= k`是为了确保在删除桶之前,窗口内始终保持最多k个元素。当`i = k`时,元素从0到k(共k+1个元素)都在窗口内,删除第0个元素是在处理第k+1个元素时进行的,即`i = k+1`时,保证窗口内只有k个元素。这种处理方式是为了维护正确的窗口大小和确保不会过早地删除元素,确保所有在窗口大小k范围内的元素都被比较,保持算法的正确性。

相关问题