數據結構刷題
1 存在重複元素
1.3
O(n)神仙解法,桶,參考自https://leetcode.com/problems/contains-duplicate-iii/discuss/339421/Python-bucket-method-in-detail
首先,定義桶的大小是t+1, nums[i]//(t+1)決定放入幾號桶,這樣在一個桶裏面的任意兩個的絕對值差值都<=t
例如t=3, nums=[0 ,5, 1, 9, 3,4],那麼0號桶就有[0,1,3],1號桶就有[4,5],2號桶就有[9]
先不考慮索引差值最大爲K的限制,那麼遍歷nums每一個元素,並把他們放入相應的桶中,有兩種情況會返回True
要放入的桶中已經有其他元素了,這時將nums[i]放進去滿足差值<=t
可能存在前面一個桶的元素並且與nums[i]的差值<=t 或者 存在後面一個桶的元素並且與nums[i]的差值<=t
根據返回True的第一個條件,可以知道前後桶的元素最多也只能有一個。
接着考慮限制桶中的索引差最大爲K,當i>=k的時候:
我們就要去刪除存放着nums[i-k]的那個桶(編號爲nums[i-k]//(t+1))
這樣就能保證遍歷到第i+1個元素時,全部桶中元素的索引最小值是i-k+1,就滿足題目對索引的限制了
class Solution:
def containsNearbyAlmostDuplicate(self, nums: List[int], k: int, t: int) -> bool:
if t < 0 or k < 0:
return False
all_buckets = {}
bucket_size = t + 1 # 桶的大小設成t+1更加方便
for i in range(len(nums)):
bucket_num = nums[i] // bucket_size # 放入哪個桶
if bucket_num in all_buckets: # 桶中已經有元素了
return True
all_buckets[bucket_num] = nums[i] # 把nums[i]放入桶中
if (bucket_num - 1) in all_buckets and abs(all_buckets[bucket_num - 1] - nums[i]) <= t: # 檢查前一個桶
return True
if (bucket_num + 1) in all_buckets and abs(all_buckets[bucket_num + 1] - nums[i]) <= t: # 檢查後一個桶
return True
# 如果不構成返回條件,那麼當i >= k 的時候就要刪除舊桶了,以維持桶中的元素索引跟下一個i+1索引只差不超過k
if i >= k:
all_buckets.pop(nums[i-k]//bucket_size)
return False
1.2
給定一個整數數組和一個整數 k,判斷數組中是否存在兩個不同的索引 i 和 j,使得 nums [i] = nums [j],並且 i 和 j 的差的絕對值最大爲 k。
# 哈希
# 初試化哈希表hash= \{\}hash={}
# 遍歷數組:
# 若nums[i]nums[i]不在hashhash中,則令nums[i]nums[i]爲key,value爲當前的索引ii。
# 若已存在:
# 判斷當前的索引和上一相同元素的索引差是否小於等於kk,即i-hash[nums[i]]<=ki−hash[nums[i]]<=k。若滿足,返回TrueTrue。
# 將索引更新爲當前索引,hash[nums[i]]=ihash[nums[i]]=i
# 返回FalseFalse
# 複雜度分析
# 時間複雜度:O\left(n\right)O(n),進行了一次遍歷。
# 空間複雜度:O(n)O(n),藉助hashhash存儲過程。
class Solution:
def containsNearbyDuplicate(self,nums:List[int],k:int) -> bool:
hash = {}
for i in range(len(nums)):
if(nums[i] not in hash):
hash[nums[i]]=i
else:
if(i - hash[nums[i]] <= k):
return True
else:
hash[nums[i]] = i
return False
1.3 給定一個整數數組,判斷是否存在重複元素。
如果任何值在數組中出現至少兩次,函數返回 true。如果數組中每個元素都不相同,則返回 false。
# class Solution:
# def containsDuplicate(self, nums: List[int]) -> bool:
# 方法1;思路:
# 思路一:暴力
# 時間複雜度:O(n^2)O(n
# 2
# )(超時)
# 無空間
# class Solution:
# def containsDuplicate(self, nums: List[int]) -> bool:
# for i in range(len(nums)):
# for j in range(i + 1, len(nums)):
# if nums[i] == nums[j]:
# return True
# return False
# 思路二:排序
# 時間複雜度:O(nlog(n))O(nlog(n))
# 無空間
# class Solution:
# def containsDuplicate(self, nums: List[int]) -> bool:
# if not nums: return False
# nums.sort()
# for i in range(1, len(nums)):
# if nums[i - 1] == nums[i]: return True
# return False
# 思路三:哈希
# 用字典記錄以及訪問的元素
# 時間複雜度:O(n)O(n)
# 空間複雜度:O(n)O(n)
class Solution:
def containsDuplicate(self, nums: List[int]) -> bool:
visited = set()
for num in nums:
if num in visited:return True
visited.add(num)
return False
11