哈希表:
常见的三种哈希结构:
- 数组(Array)
- 集合(Set)
- 映射(Map)
当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法
数组作为哈希表: 代表题目(242.有效字母异位词)
- 适用于已知大小、需要按顺序或随机访问元素的场景
集合作为哈希表: 代表题目(349. 两个数组的交集)
- 适用于需要保证元素唯一性、去重或进行集合运算的场景;亦或者数字特别大,并且没有数字的限制;
映射作为哈希表: 代表题目(1. 两数之和)
- 适用于需要通过键值对存储和管理关联关系的场景
242. 有效字母异位词
- 因为题目是26个英文字母小写,所以我们第一时间要想到使用数组因为数量有限并且是连续的数据
- 创建一个空间为26的数组,用来存储字符串字母出现的频率
- 我们通过使用ascii码做减法可以得知该字母在哈希数组中对应存储的位置,如果字符串中出现过我们就 + 1,代表着出现过一次
- 让两个哈希数组进行比对,如果每个字符出现的频率一样返回True,否则返回False
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
# since only contain lowercase letter, means we can use array
result1 = [0 * n for n in range(26)]
result2 = [0 * j for j in range(26)]
# record each string letter appear frequency
for i in s:
# use ord to convert letter to ascii number;
# ex: c-a = 99-97; at result1 index 2 position + 1, means c appear in the string
result1[ord(i) - ord('a')] += 1
# record second string
for j in t:
result2[ord(j) - ord('a')] += 1
count = 0
# compare those two array, check the frequency is same or not
while count < len(result1):
if result1[count] != result2[count]:
# means two string have different letter
return False
count += 1
# they have same letter
return True
349. 两个数组的交集
- 由于我们不能有重复的元素 并且数据并不知道会有多少 这题用set集合作为哈希表
- 使我们其中一个数组放到set当中,循环判断另外一个数组的数字是否在set中
- 如果在把该元素添加到新的set中当作答案保存,返回结果时不要忘记转换回数组
class Solution(object):
def intersection(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
# create a saet put one of array inside the hash table
number_set = set(nums1)
result = set()
# check nums2 is insde numer_set or not
for i in range(len(nums2)):
if nums2[i] in number_set:
# means they have intersection
result.add(nums2[i])
# return our array; first convert set back to array
return list(result)
1. 两数之和
- 使用map映射关系来分别存储数组里元素的值和下标
- 注意: 保存到map中的时候,一定要让元素作为key来存储
- 由于两数之和 target - value(目前的遍历到的元素) 可以得到我们需要什么数组相加可以满足目标值
- 如果该数字在我们map中,即可返回数组下标位置,第一个位置就是我们map对应key的value(map中的value保存的时对应元素的下标),第二个就是目前元素的下标
- 如果该数字不在我们就把当前数字保存到map中
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
# using map to be our hash table
hash_table = dict()
# iterate array, key be our element, value to be our index
for index,value in enumerate(nums):
# use target - current get value we want to check in our dict
number = target - value
if number in hash_table:
# mean's we have this number in our dict, we can return index
return [hash_table[number],index]
# we don't have that value in our dict, we should add to it
hash_table[value] = index
# if can't find it return empty array
return []
202.快乐数
- 数据量未知,需要判断是否有重复的数字出现,使用set作为哈希表
- 编写一个函数用来每次获取每一位的数字并使其平方相加然后返回改值
- 如果n不等于1,我们应该先把改数字添加到set,然后再次调用获取每一位数字的函数,先添数字这一步避免了进入无限循环导致报错
- 举例: 假设题目初始值为19,由于我先调用函数所以导致19并没有添加到我们set中,后续一直循环会因为没有19一直跑下去
class Solution(object):
def isHappy(self, n):
"""
:type n: int
:rtype: bool
"""
# use a set to contain number, aviod duplicate number appear
result = set()
while True:
# if n == 1 return
if n == 1:
return True
# check if n is appear in result
if n in result:
return False
else:
# we should add n to set first, to aviod infinite loop
result.add(n)
n = self.get_number(n)
# get every digit
def get_number(self,n):
sum_ = 0
# in case is not only two digit quesiton
while n > 0:
# to get each digit
digit = n % 10
# add them
sum_ += digit**2
# ready to get next digit
n = n//10
return sum_