Contains Duplicate III
题目描述
Given an array of integers, find out whether there are two distinct indices i and j in the array such that the difference between nums[i] and nums[j] is at most t and the difference between i and j is at most k.
解题方法
从index的difference最多为k我们可以感觉有点像sliding window, 在Move的过程中增加和减少element, 而如果对于每一个value, 都要将[value-t, value + t]这个范围找一遍的话,肯定时间复杂度太高。
利用Bucket sort的思想
如果需要在一定等间隔范围的查找,可以利用bucket sort的思想减小查找比较的范围
如果: | nums[i] - nums[j] | <= t 式a
等价: | nums[i] / t - nums[j] / t | <= 1 式b
推出: | floor(nums[i] / t) - floor(nums[j] / t) | <= 1 式c
等价: floor(nums[j] / t) ∈ {floor(nums[i] / t) - 1, floor(nums[i] / t), floor(nums[i] / t) + 1} 式d
那么对于每一个Num,只要
key = num / t
然后搜寻(key-1, key, key + 1)是否在维护的最大size为k的map中,并且判断真实的value diff是否<= t就可以了。
快速delete开头的key/value pair
在sliding window总我们用hashheap, 在Python中有OrderedDict这个数据结构,可以用在这里
OrderedDict.popitem(last=True)
The popitem() method for ordered dictionaries returns and removes a (key, value) pair.
The pairs are returned in LIFO order if last is true or FIFO order if false.
Solution
from collections import OrderedDict
class Solution(object):
def containsNearbyAlmostDuplicate(self, nums, k, t):
"""
:type nums: List[int]
:type k: int
:type t: int
:rtype: bool
"""
if not nums:
return False
if t < 0 or k < 1:
return False
window = OrderedDict()
for idx, num in enumerate(nums):
# bucket size should be at least 1
key = num / max(1, t)
for i in (key, key-1, key+1):
if i in window and abs(window[i] - num) <= t:
return True
window[key] = num
if idx >= k:
window.popitem(last=False)
return False