哈希表
基本知识:
哈希表,hash table,散列表
简单来说,数组就是一个哈希表,通过数组的索引访问数组中的元素
哈希表一般用来判断:一个元素是否存在于一个集合汇总
举个例子:
查询一个学生的名字是否在这所学校里,在初始化的时候,使用hash function来将这个学生的名字映射到哈希表上,查询的时候通过索引就可以知道这位同学在不在这所学校里了
hash function:
通过hashcode将名字转化为数值,然后用hash function将学生名字映射到哈希表上的索引数字
哈希碰撞
主要就是当两个名字映射出来的索引数值落在同一个索引下标的位置。
或者说,当学生的数量大于哈希表的大小时候,那么一定会有不同的学生落在重复的位置,这个时候就叫哈希碰撞。
哈希碰撞的解决方法
拉链法
拉链法的关键在于,寻找一个比较合适的数组大小,既不会出现大量的空值,又不会因为链表太长查找时间过长
线性探测法
我的理解就是,冲突以后,就往下找一格放置小王,要注意的是,tablesize一定要大于datasize
242 有效地字母异位词
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
#ord()函数用于将一个字符转换为对应的ASCII数值或者Unicode数值
#注意到s,t仅包含小写字母,那么ASCII码从a开始仅有26位
if len(s) != len(t):
return False
record = [0]*26
for i in range(len(s)):
record[ord(s[i])-ord("a")] += 1
for i in range(len(t)):
record[ord(t[i])-ord("a")] -= 1
for i in range(26):
if record[i] != 0:
return False
return True
总结:方法挺巧妙地,将字符串对应为数字(只有26个小写字母),然后用一个数组(哈希表),存储出现的次数,在遍历第二个字符串的时候,将每次出现的字符对应的数字所在索引位置数值-1,最后检查record[]数组是否全部为0,若有不为0,则不为字母异位词。
349 两个数组的交集
给定两个数组 nums1 和 nums2 ,返回 它们的 交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
class Solution(object):
def intersection(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
return list(set(nums1) & set(nums2)) # 两个数组先变成集合,求交集后还原为数组
使用set()函数将nums1和nums2变为集合,也就是去掉重复的元素
再求交集
最后再转化为数组list()
202 快乐数
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false
class Solution(object):
def isHappy(self, n):
"""
:type n: int
:rtype: bool
"""
set_ = set()
while 1:
sum_ = self.getsum(n)
if sum_ == 1:
return True
if sum_ in set_:
return False
else:
set_.add(sum_)
n = sum_
#首先定义一个函数求每个位上的单数平方和
def getsum(self,n):
sum_=0
while n>0 :
sum_ += (n%10)*(n%10)
n = n//10#取整除
return sum_
总结:本题求每个n的每位平方和倒不难,主要是判定
首先使用一个集合set_ ,其中不会出现重复的数字
然后开始循环,一遍遍的求平方和,若是结果为1,则返回True,若是结果不为1,则判定set_中有无相同数字,若无则存入set_中,若存在,则表明陷入死循环中,return False
1 两数之和
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
hashtable = dict()
for i,num in enumerate(nums):
if target-num in hashtable:
return (hashtable[target-num],i)
hashtable[nums[i]] = i
return
总结:使用了python中的字典dict()
将nums[]的只作为字典的键,将nums的索引作为字典的值。
hashtable[nums[i]] = i