您的位置:首页 > 大数据 > 人工智能

【Leetcode】220. Contains Duplicate III 存在重复元素 III

2019-01-31 18:24 585 查看

解法

本题的关键其实是滑动窗口,需要判断

nums[i]
前长度为
k
的窗口里有没有
[nums[i]-1,nums[i]+t]
范围内的数
要注意k和t都有可能是负数……神坑

解法一:离散化+BIT

我自己用的比较naive的BIT来做的,非常不美= =

class Solution(object):
def containsNearbyAlmostDuplicate(self, nums, k, t):
"""
:type nums: List[int]
:type k: int
:type t: int
:rtype: bool
"""
n = len(nums)
if n==0 or k<0 or t<0:
return False
from bisect import bisect_right,bisect_left
unique = sorted(set(nums))
idx = {}
for i,v in enumerate(unique):
idx[v] = (i+2,bisect_left(unique,v-t,hi=i)+1,bisect_right(unique,v+t,lo=i)+1)
l = len(unique)+1
c = [0]*l
def lowbit(k):
return k&-k
def add(k,val):
while k<=l:
c[k-1] += val
k += lowbit(k)
def csum(k):
res = 0
while k>=1:
res += c[k-1]
k -= lowbit(k)
return res
for i,a in enumerate(nums):
if i>k:
add(idx[nums[i-k-1]][0],-1)
if csum(idx[a][2])-csum(idx[a][1]):
return True
add(idx[a][0],1)
return False

解法二:滑动窗口+treemap

主要利用treemap的排序性质,然而,python没有treemap= =

解法三:滑动窗口+桶排序

这个思路太巧了
首先划分桶,我们想想与一个数差距不超过

t
,那么也就是说差距可以是
0,1,...,t
,我们将
nums[i]//(t+1)
相同的数都放到一个桶里,这个桶里的数字之间差距一定不超过
t
,此外,相邻的桶里也有可能有差距不超过t的数字,所以我们还要check一下桶
nums[i]//(t+1)-1
和桶
nums[i]//(t+1)-1

注意:
实际编程时每个桶用int存而不需要用list存,这是因为每个时刻每个桶里最多只可能有一个数,有两个数的时候已经直接返回
True
了。

class Solution(object):
def containsNearbyAlmostDuplicate(self, nums, k, t):
"""
:type nums: List[int]
:type k: int
:type t: int
:rtype: bool
"""
if len(nums)==0 or t<0 or k<0:
return False
from collections import defaultdict
t += 1
record = {}
for i,c in enumerate(nums):
if i>k and nums[i-k-1]//t in record:
# 新的窗口内一定没有桶nums[i-k-1]//t里的数
# 否则在遍历到nums[i-k-1]就会返回真
record.pop(nums[i-k-1]//t)
if c//t in record or (c//t-1 in record and c-record[c//t-1]<t) or (c//t+1 in record and record[c//t+1]-c<t):
return True
# 此处record里一定没有c//t
# 否则前面会返回真
record[c//t]=c
return False
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: