https://leetcode.com/problems/contains-duplicate-iii/
桶排序的思想,很少碰到,但是的确很精妙。
个人解答
class Solution:
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
bucket = {} # numbers in same bucket, have difference <= t
bucketSize = t + 1
for i, x in enumerate(nums):
idx = x // bucketSize
# check three possible condition, current bucket and neighbor buckets
if idx in bucket:
return True
if idx - 1 in bucket and abs(bucket[idx - 1] - nums[i]) <= t:
return True
if idx + 1 in bucket and abs(bucket[idx + 1] - nums[i]) <= t:
return True
bucket[idx] = x
# remove out bound value
if i - k >= 0:
del(bucket[nums[i - k] // bucketSize])
return False
题目分析
之前的contain duplicate问题,由于idx范围的限制,很容易想到要用sliding window,这道题也有这样的设定,但是对于如何判断duplicate,本题并不能直接相等判断。
所以,本题关键是如何快速判断当前窗口中的所有值,是否有与之相距<=t的,而这就要用到桶排序的思想,每t+1搁长度的区间构成一个桶,如此,有两种情况两个值相距可能<=t:
- 两数在同一个桶之中
- 两数在相邻桶之中
这样,最多只要判断三个数就可以完成!
维护这样的桶也比较容易,每次窗口前进一步的时候,就把之前的桶里对应的值删掉。