桶分类以查找附近几乎重复的物品

时间:2019-04-08 03:15:56

标签: python

我正在研究问题Contains Duplicate III - LeetCode

  

给出一个整数数组,找出数组中是否存在两个不同的索引 i j ,以使它们之间的绝对差异 nums [i] nums [j] **最多是 t ,而 i 是不同的>和 j 最多为 k

     

示例1:

Input: nums = [1,2,3,1], k = 3, t = 0
Output: true
     

示例2:

Input: nums = [1,0,1,1], k = 1, t = 2
Output: true
     

示例3:

Input: nums = [1,5,9,1,5,9], k = 2, t = 3
Output: false

在讨论区中阅读存储桶排序解决方案

class Solution2:
    def containsNearbyAlmostDuplicate(self, nums, k, t):
        if t < 0: return False
        lookup = {}
        for i in range(len(nums)):
            b_idx = nums[i] // (t+1) 
            if b_idx in lookup:
                return True
            if b_idx - 1 in lookup and abs(nums[i] - lookup[b_idx - 1]) < t+1:
                return True
            if b_idx + 1 in lookup and abs(nums[i] - lookup[b_idx + 1]) < t+1:
                return True
            lookup[b_idx] = nums[i] 
            if i >= k: del lookup[nums[i-k] // (t+1)]
        return False    

说明

  

这个想法就像存储桶排序算法。假设我们有连续的存储桶,覆盖了num的范围,每个存储桶的宽度为(t + 1)。如果存在两项差异<= t的项目,则将发生以下两项之一:
      (1)两个在同一个桶中
      (2)邻居桶中的两个

我了解存储桶排序的逻辑,但不知道此解决方案的工作原理。

我认为,有必要在宽度范围内的所有值之间进行比较,但是解决方案仅比较相同的存储桶和相邻的存储桶

del lookup[num[i-k],我不知道这种操作的目的。

1 个答案:

答案 0 :(得分:4)

第一个问题: 为什么只比较同一桶和相邻桶?

正如作者所说,如果(a, b)是有效对,有两种情况:

  

(1)两者位于同一存储桶中
  (2)邻居桶中的两个

如果b - a <= t仅表示上述两种情况,则可以通过此处的存储桶示例来了解它:

  

<-a-- t + 1 --- b-> <----- t + 1 ----->在同一存储桶中
  <----- t + 1 --a-> <--- b- t + 1 ----->在邻居桶中

之所以使用

Bucket是因为我们希望将范围划分为偶数宽度,并减少比较时间。这是一种交换时间的方法。


第二个问题:为什么del lookup[num[i-k]

由于第二个限制是差异索引ij最多应为k。

因此,在for i in range(len(nums)):中,如果是i - j == k,则应从存储桶中删除先前的索引j。并且包括等于k的差,因此我们应该在逻辑之后删除。

如果您不这样做,则会找到abs(nums[i]-nums[j])<=tabs(i-j)>t


我希望我能说清楚,如果您还有其他问题,请发表评论。 :)


顺便提一句建议:如果您感到困惑或困惑,可以通过打印或调试来查看示例,您会更加清楚,尤其是在极端情况下。