题目来源:
https://leetcode.com/problems/contains-duplicate-ii/description/
题目分析:
本题是要给定一个整数数组和整数k,找出数组中是否存在两个不同的索引i和j,使得NUMS[i]=NUMS[j]并且i和j之间的绝对差值至多k。
最简单的想法是采用循环二重检索,但是时间复杂度太高不能通过,将代码写在下方:
class Solution:
def containsNearbyDuplicate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
for i in range(len(nums)-1):
for j in range(i+1,len(nums)):
if(nums[i]==nums[j] and (j-i)<=k):
return True
return False
第二种思路类似于Hashmap思想(也可能就是),就是利用python中的字典结构。遍历所有元素,将元素值当做键、元素下标当做值,存放在一个字典中。遍历的时候,如果发现重复元素,则比较其下标的差值是否小于k,如果小于则可直接返回True,否则更新字典中该键的值为新的下标。
class Solution:
def containsNearbyDuplicate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
t={}
for i in range(len(nums)):
if(nums[i] in t and i-t[nums[i]]<=k):
return True
else:
t[nums[i]]=i
return False
第三种思想是利用Hashset思想(不知道是不是),就是利用窗口的想法来实现。在python中应用到set(集合)的类型,它是一个无序不重复的元素集。对于集合蕴含的方法,可以详见https://www.cnblogs.com/lemonbit/p/6239156.html。则本题的思想是在遍历列表的时候维护一个集合,集合中保存当前元素前面的k个元素,每次访问一个元素时判断是否在该集合中出现过。
class Solution(object):
def containsNearbyDuplicate(self, nums, k):
"""
:type nums: List[int]
:type k: int
:rtype: bool
"""
window = set([])
for i in range(len(nums)):
if i > k:
window.discard(nums[i-k-1])
if nums[i] in window:
return True
else:
window.add(nums[i])
return False
set.remove(obj)和set.discard(obj)的区别在于,当obj存在于set中时,都将其删除;但当obj不存在于set中时,remove()会报错,discard()不会。