一:LeetCode242.有效的字母异位词
1:题目描述(242.有效的字母异位词)
给定两个字符串 s 和 t ,编写一个函数来判断 t 是否是 s 的字母异位词。
注意:若 s 和 t 中每个字符出现的次数都相同,则称 s 和 t 互为字母异位词。
2:解题思路
使用哈希表-数组:
- 因为只包含小写字母,所以我们使用小写字母的ASCII码,来作为数组的索引;
- 数组固定长度为26,初始化值为0;
- 先遍历字符串s,统计字符串s中每个字符出现的次数;
- 再遍历字符串t,然后在数组中,减去t中字符出现的次数;
- 判断数组的元素是否全为0,有不为0的,则表示s和t不是字母异位词;
class Solution:
def isAnagram(self, s, t):
# 使用哈希表-数组
# 因为只包含小写字母,所以我们使用小写字母的ASCII码,来作为数组的索引
# 数组固定长度为26,初始化值为0
# 先遍历字符串s,统计字符串s中每个字符出现的次数
# 再遍历字符串t,然后在数组中,减去t中字符出现的次数
# 判断数组的元素是否全为0,有不为0的,则表示s和t不是字母异位词
res = [0] * 26
for i in range(len(s)):
res[ord(s[i]) - ord("a")] += 1
for j in range(len(t)):
res[ord(t[j]) - ord("a")] -= 1
for n in range(len(res)):
if res[n] != 0:
return False
return True
二、LeetCode349. 两个数组的交集
1:题目描述(349. 两个数组的交集)
给定两个数组 nums1
和 nums2
,返回 它们的交集 。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
2:解题思路
解法一:哈希表-数组:
- 因为元素是固定的,0到1000,所以我们可以定义一个数组res_mid,来统计nums1中数字出现的次数,索引为nums1/nums2中的元素,值为nums1中数字出现的次数;
- 定义一个存放结果的数组;
- 先遍历nums1,统计nums1中数字出现的次数;
- 再遍历nums2,判断nums2中数字在数组res_mid中索引对应的值是否大于0;
- 大于0,则表示数字在nums1中出现过,就将这个数字加入到res中;
- 等于0,则表示数字未在nums1中出现过,就继续遍历nums2;
- 最后使用set()对res进行去重,然后以列表的形式返回。
class Solution:
def intersection(self, nums1, nums2):
# 因为元素是固定的,0到1000,所以我们可以定义一个数组res_mid,来统计nums1中数字出现的次数,索引为nums1/nums2中的元素,值为nums1中数字出现的次数
# 定义一个存放结果的数组
# 先遍历nums1,统计nums1中数字出现的次数
# 再遍历nums2,判断nums2中数字在数组res_mid中索引对应的值是否大于0
# 大于0,则表示数字在nums1中出现过,就将这个数字加入到res中
# 等于0,则表示数字未在nums1中出现过,就继续遍历nums2
# 最后使用set()对res进行去重,然后以列表的形式返回
res_mid = [0] * 1005
res = []
for i in range(len(nums1)):
res_mid[nums1[i]] += 1
for j in range(len(nums2)):
if res_mid[nums2[j]] > 0:
res.append(nums2[j])
return list(set(res))
解法二:直接将两个数组变成集合,然后求交集
class Solution:
def intersection(self, nums1, nums2):
# 将两个数组变成集合后,求两个集合的交集
return list(set(nums1) & set(nums2))
三、LeetCode202. 快乐数
1:题目描述(202. 快乐数)
编写一个算法来判断一个数 n 是不是快乐数。
「快乐数」 定义为:
对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n 是 快乐数 就返回 true ;不是,则返回 false 。
2:解题思路
使用哈希表-数组:
- 将正整数变成字符串,然后遍历字符串,对每个位置上的数字转化为int类型进行求和
- 然后将求和的结果,再次作为一个正整数进行判断,一直循环,直到最后的求和结果等于1,结束循环,返回True
- 如果始终变不到1,那么我们就需要判断每次得到的求和结果是否已经出现过
- 所以,使用哈希表-数组,将每次得到的求和结果放到数组中,如果已经在数组中出现过,则直接返回False,未出现过,则继续循环。
class Solution:
def isHappy(self, n):
# 将正整数变成字符串,然后遍历字符串,对每个位置上的数字转化为int类型进行求和
# 然后将求和的结果,再次作为一个正整数进行判断,一直循环,直到最后的求和结果等于1,结束循环,返回True
# 如果始终变不到1,那么我们就需要判断每次得到的求和结果是否已经出现过
# 所以,使用哈希表-数组,将每次得到的求和结果放到数组中,如果已经在数组中出现过,则直接返回False,未出现过,则继续循环
m = n
list1 = []
while m != 1:
m = str(m)
list_sum = 0
for i in m:
list_sum += (int(i) * int(i))
if list_sum in list1:
return False
list1.append(list_sum)
m = list_sum
return True
四、LeetCode1. 两数之和
1:题目描述(1. 两数之和)
给定一个整数数组 nums 和一个整数目标值 target,请你在该数组中找出 和为目标值 target 的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
2:解题思路
解法一:使用两个for循环进行遍历数组
- 遍历数组nums,判断当前元素与后面元素的和是否等于目标值target;
- 等于则将两个元素的索引返回;
- 不等于,则减去对应的元素值,继续循环。
class Solution:
def twoSum(self, nums, target):
# 遍历数组nums,判断当前元素与后面元素的和是否等于目标值target
# 等于则将两个元素的索引返回
nums_sum = 0
for i in range(len(nums)):
nums_sum += nums[i] # 当前元素与nums_sum进行求和
for j in range(i+1, len(nums)): # 遍历当前元素之后的元素
nums_sum += nums[j] # 与nums_sum进行求和
if nums_sum == target: # 判断nums_sum是否等于target
return [i,j] # 等于,则将两个索引返回
else: # 不等于,则将j对应的元素减去,继续循环判断后面的值
nums_sum -= nums[j]
nums_sum -= nums[i] # 当前元素与后面的元素都不满足时,将当前元素从nums_sum中减去,进入下一个元素的求和
解法二:使用哈希表-字典
- 定义一个字典res,将已遍历的元素放到res中,key值表示元素的值,value表示元素在数组中对应的索引
- 遍历数组nums,用目标值减去遍历的值,然后去res中查找是否有遍历到这个值
- res中存在这个值,则找到了符合要求的两个元素,返回这个值在res中的value值和当前遍历到nums的元素的下标
- res中不存在这个值,则将当前遍历的元素,加入到res中,元素值为key,索引为value。
class Solution:
def twoSum(self, nums, target):
res = dict()
for k, v in enumerate(nums): # 遍历数组,使用枚举,k为索引,v为元素值
if target-nums[k] in res: # 判断target-nums[k]得到的值,是否存在于res中
return [res[target-nums[k]], k] # 存在则,返回target-nums[k]在res中对应的value值,和当前遍历元素的索引k
res[nums[k]] = k # 不存在,则将遍历的元素,加入到res中,元素值为key,索引为value
return None
今日总结:
今天需要牢记一句话: 当我们遇到了要快速判断一个元素是否出现集合里的时候,就要考虑哈希法。