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 <= tbucketSize = t + 1for i, x in enumerate(nums):idx = x // bucketSize# check three possible condition, current bucket and neighbor bucketsif idx in bucket:return Trueif idx - 1 in bucket and abs(bucket[idx - 1] - nums[i]) <= t:return Trueif idx + 1 in bucket and abs(bucket[idx + 1] - nums[i]) <= t:return Truebucket[idx] = x# remove out bound valueif i - k >= 0:del(bucket[nums[i - k] // bucketSize])return False
题目分析
之前的contain duplicate问题,由于idx范围的限制,很容易想到要用sliding window,这道题也有这样的设定,但是对于如何判断duplicate,本题并不能直接相等判断。
所以,本题关键是如何快速判断当前窗口中的所有值,是否有与之相距<=t的,而这就要用到桶排序的思想,每t+1搁长度的区间构成一个桶,如此,有两种情况两个值相距可能<=t:
- 两数在同一个桶之中
- 两数在相邻桶之中
这样,最多只要判断三个数就可以完成!
维护这样的桶也比较容易,每次窗口前进一步的时候,就把之前的桶里对应的值删掉。
