直接查询关键字,不用像数组那样需要取下标。
解决冲突的方法:拉链法
list(列表,可重复,插入O(1),查找O(n))
map(映射):Python中的dict字典,用哈希表存储。
set:集合,不允许重复,哈希表或者树实现,查找O(1)或O(logN)。哈希表查找速度快,但是二叉树有序排列。
leetcode题目:
1、有效的字母异位词
https://leetcode-cn.com/problems/valid-anagram/description/
方法一:两个单词排序后比较。时间复杂度O(nlogn)
方法二:记录每个字符在单词中出现的次数,时间复杂度O(n)
class Solution:
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
dict_s, dict_t = {},{}
for c in s:
dict_s[c] = dict_s.get(c,0)+1 # 获取c键值对应的数值+1
for c in t:
dict_t[c] = dict_t.get(c,0)+1
return dict_s == dict_t
2、两数之和
https://leetcode-cn.com/problems/two-sum/description/
方法一:两层循环
方法二:列举每个x,在列表中查找是否有9-x。由于列表查找的时间复杂度为O(n),为了提高算法速度,可以转换成字典再查找。
以下是直接列表查找的代码:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums)<=1:
return []
for i,num in enumerate(nums):
if target-num in nums[i+1:] :
return [i,nums[i+1:].index(target-num)+i+1]
return []
列表转字典优化后的代码:
class Solution:
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
n =len(nums)
d = {}
for i in range(n):
a = target - nums[i]
if nums[i] in d:
return d[nums[i]],i
else:
d[a] = i
3、三数之和
方法一:两次循环遍历,第三个数存字典查询
class Solution:
def threeSum(self, nums):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums)<3:
return []
nums.sort() # 解决多个重复值情况
res = set() # 保证没有重复结果
for i ,v in enumerate(nums):
if i>0 and v == nums[i-1]: # 当有重复值时,第层遍历只使用一个值
continue
d = {}
for x in nums[i+1:]:
if x in d:
res.add((v,x,-v-x)) # 若字典中有该相反数,则说明有三数和等于0,加入结果
else:
d[-v-x] = 1 # 如果字典中没有两值和的相反数,将该相反数加入字典
return list(res)
方法二:双指针法
class Solution:
def threeSum(self, nums):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
if len(nums)<3:
return []
nums.sort()
res = set()
for i ,v in enumerate(nums):
if i>0 and v == nums[i-1]:
continue
head = i+1
tail = len(nums)-1
while head<tail:
s = nums[head]+nums[tail]+v
if s== 0:
res.add((nums[i],nums[head],nums[tail]))
head += 1
tail -= 1
elif s>0:
tail -= 1
else:
head += 1
return list(res)