一、今日任务
二、哈希表理论基础
哈希表是根据关键码的值而直接进行访问的数据结构。
一般哈希表都是用来快速判断一个元素是否出现集合里。
将学生姓名映射到哈希表上就涉及到了hash function ,也就是哈希函数。
涉及到的是哈希函数,用以确定位置,哈希碰撞方法用以解决出现冲突。最基本的两个方法是拉链法和线性探测法。
总结一下,当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。
但是哈希法也是牺牲了空间换取了时间,因为我们要使用额外的数组,set或者是map来存放数据,才能实现快速的查找。
如果在做面试题目的时候遇到需要判断一个元素是否出现过的场景也应该第一时间想到哈希法。
常用的数据结构是数组、set和map。
三、有效的字母异位词
3.1 题目:242. 有效的字母异位词
3.2 解题过程
就是比较简单的思路,利用两个数组记录,然后再对比两个记录数组:
class Solution(object):
def isAnagram(self, s, t):
"""
:type s: str
:type t: str
:rtype: bool
"""
s_list = [0]*26
t_list = [0]*26
if len(s) != len(t):
return False
for i, j in zip(s, t):
s_list[ord(i)-ord('a')] += 1 # ord函数得出对应Ascii
t_list[ord(j)-ord('a')] += 1
for index in range(0,25):
if s_list[index] != t_list[index]:
return False
return True
3.3 阅读材料改进
思路一致。
四、两个数组的交集
4.1 题目:349. 两个数组的交集
4.2 解题过程
看题目,是一个非常简单的题目,就是要求交集,返回的交集,集合要保持无重复,无序也ok。
首先想到思路和上一题一致。
class Solution(object):
def intersection(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
nums1_hashtable = [0]*1001
nums2_hashtable = [0]*1001
rnums = []
for i in nums1:
if nums1_hashtable[i] == 0:
nums1_hashtable[i] = 1
for j in nums2:
if nums2_hashtable[j] == 0:
nums2_hashtable[j] = 1
index = 0
for i,j in zip(nums1_hashtable, nums2_hashtable):
if i == 1 and j == 1:
rnums.append(index)
index += 1
return rnums
4.3 阅读材料改进
随想录提出如果是没定义元素大小,那么数组做哈希表的算法是没有办法实现的。
因此,要考虑更加通用的的方法。这时可以利用python语言的结构字典。
复现代码如下:
class Solution(object):
def intersection(self, nums1, nums2):
"""
:type nums1: List[int]
:type nums2: List[int]
:rtype: List[int]
"""
rnums = []
nums1_dict = {}
for i in nums1:
nums1_dict[i] = 1
for j in nums2:
if j in nums1_dict.keys() and nums1_dict[j] == 1:
rnums.append(j)
nums1_dict[j] = 0
return rnums
五、快乐数
5.1 题目:202. 快乐数
5.2 解题过程
主要的如何判断循环。
class Solution(object):
def isHappy(self, n):
"""
:type n: int
:rtype: bool
"""
num_dict = {}
while 1:
num_dict[n] = 1
str_n = str(n)
sum = 0
for i in str_n:
m = ord(i)-ord('0')
sum += m*m
n = sum
if sum == 1:
return True
if sum in num_dict.keys():
break
return False
5.3 阅读材料改进
自己使用的是比较偏门的方法求取各个单位上的数,然后也没有使用set,以下是复现代码:
def getelem(self, n):
sum = 0
while n :
sum += (n%10) ** 2
n = n//10
return sum
def isHappy(self, n):
"""
:type n: int
:rtype: bool
"""
record = set()
sum = n
while 1:
sum = self.getelem(sum)
if sum == 1:
return True
if sum in record:
break
record.add(sum)
return False
六、1. 两数之和
6.1 题目:1. 两数之和
6.2 解题过程
暴力方法先上:
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
for i in range(0, len(nums)):
for j in range(i, len(nums)):
if i != j and nums[i]+nums[j]==target:
return [i, j]
接下来思考如何O(n)完成:
class Solution(object):
def twoSum(self, nums, target):
"""
:type nums: List[int]
:type target: int
:rtype: List[int]
"""
record = {}
for i in range(0, len(nums)):
if target-nums[i] in record.keys():
return [record[target-nums[i]], i]
record[nums[i]] = i
6.3 阅读材料改进
首先我在强调一下 什么时候使用哈希法,当我们需要查询一个元素是否出现过,或者一个元素是否在集合里的时候,就要第一时间想到哈希法。
map就对应于python里的字典。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
records = dict()
for index, value in enumerate(nums):
if target - value in records: # 遍历当前元素,并在map中寻找是否有匹配的key
return [records[target- value], index]
records[value] = index # 遍历当前元素,并在map中寻找是否有匹配的key
return []