哈希表是用来快速判断一个元素是否出现集合里
牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找
要枚举的话时间复杂度是O(n),但如果使用哈希表的话, 只需要O(1)就可以做到, 在查询的时候通过索引
三种数据结构
- 数组
- set (集合)
- map(映射)
242.有效的字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
定义一个数组,来记录字符串s里字符出现的次数
因为字符a到字符z的ASCII是26个连续的数值,所以字符a映射为下标0,相应的字符z映射为下标25, 字母到ASCII码转换, 用ord
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
record = [0] * 26
for i in s:
record[ord(i) - ord('a')] += 1
for i in t:
record[ord(i) - ord('a')] -= 1
for i in record:
if i != 0:
return False
return True
349. 两个数组的交集
给定两个数组 nums1
和 nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
- 如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费
- 直接使用set 不仅占用空间比数组大,而且速度要比数组慢,set把数值映射到key上都要做hash计算的
用set
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return list(set(nums1) & set(nums2))
用数组, 因为规定了数值范围0-1000
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
hash_table = [0] * 1005
result = set()
for i in nums1:
hash_table[i] = 1
for i in nums2:
if hash_table[i] == 1:
print(i)
result.add(i)
return list(result)
202. 快乐数
编写一个算法来判断一个数 n
是不是快乐数。
使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false, 否则一直找到sum为1为止
求和的过程,如何对取数值各个位上的单数操作
class Solution:
def isHappy(self, n: int) -> bool:
def get_sum(num):
total = 0
while num:
digit = (num % 10)
total += digit * digit
num = num // 10
return total
result = set()
count = get_sum(n)
while count not in result:
result.add(count)
if count == 1:
return True
count = get_sum(count)
return False
1. 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
思路: 需要一个集合来存放我们遍历过的元素,然后在遍历数组的时候去询问这个集合,某元素是否遍历过,也就是是否出现在这个集合。
不仅要知道元素有没有遍历过,还有知道这个元素对应的下标,需要使用 key value结构来存放,key来存元素,value来存下标,那么使用map正合适
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
hash_table = dict()
for i in range(len(nums)):
delta = target - nums[i]
if delta in hash_table:
return [hash_table[delta], i]
hash_table[nums[i]] = i