LeetCode 242.有效的字母异位词
文档讲解:代码随想录
视频讲解:学透哈希表,数组使用有技巧!Leetcode:242.有效的字母异位词_哔哩哔哩_bilibili
题目链接:. - 力扣(LeetCode)
给定两个字符串 s
和 t
,编写一个函数来判断 t
是否是 s
的字母异位词。
注意:若 s
和 t
中每个字符出现的次数都相同,则称 s
和 t
互为字母异位词。
示例 1:
输入: s = "anagram", t = "nagaram" 输出: true
1、思路
- 数组其实就是一个简单哈希表,这道题中字符串只有小写字母,可定义一个数组,来记录字符串s里字符出现过的次数
- 需要把字符映射到数组也就是哈希表的索引下标上,定义一个数组叫record,大小为26,初始为0,因为字符a到z的ASCII也是26个连续的数值,字符a映射为下标0,z映射为下标25
- 统计字符串s中字符出现的次数,举例s="aee",t="eae",在遍历字符串s的时候,只需要将s[i]-'a'所在的元素做+1操作即可,并不需要记住字符a的ASCII,只要求出一个相对数值就可以了。
- 检查字符串t中是否出现了这些字符,在遍历字符串t的时候,对t 中出现的字符映射哈希表索引上的数值再做-1的操作
- 最后检查一下,record数组如果有的元素不为0,说明字符串s和t一定是谁多了字符或者谁少了字符,return false,最后如果record数组所有元素都为0,return true.
时间复杂度:O(n)
空间复杂度:O(1)
2、代码
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
record = [0] * 26
for i in s:
#并不需要记住字符a的ASCII,只要求出一个相对数值就可以了
record[ord(i) - ord("a")] += 1
for i in t:
record[ord(i) - ord("a")] -= 1
for i in range(26):
if record[i] != 0:
#record数组如果有的元素不为零0,说明字符串s和t 一定是谁多了字符或者谁少了字符。
return False
return True
LeetCode 349.两个数组的交集
文档讲解:代码随想录
视频讲解:学透哈希表,set使用有技巧!Leetcode:349. 两个数组的交集_哔哩哔哩_bilibili
题目链接:. - 力扣(LeetCode)
给定两个数组 nums1
和 nums2
,返回 它们的 交集。输出结果中的每个元素一定是 唯一 的。我们可以 不考虑输出结果的顺序 。
示例 1:
输入:nums1 = [1,2,2,1], nums2 = [2,2] 输出:[2]
1、思路
如果哈希值比较少、特别分散、跨度非常大,使用数组就造成空间的极大浪费。可以使用set.
本题使用unordered_set,使用unordered_set读写效率是最高的,并不需要对数据进行排序,还不要让数据重复。
如图:
时间复杂度:O(m+n)
空间复杂度:O(n)
2、代码
(版本一)使用字典和集合
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 使用哈希表存储一个数组中的所有元素
table = {}
for num in nums1:
table[num] = table.get(num, 0) + 1
# 使用集合存储结果
res = set()
for num in nums2:
if num in table:
res.add(num)
del table[num]
return list(res)
(版本二)使用数组
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
count1 = [0]*1001
count2 = [0]*1001
result = []
for i in range(len(nums1)):
count1[nums1[i]]+=1
for j in range(len(nums2)):
count2[nums2[j]]+=1
for k in range(1001):
if count1[k]*count2[k]>0:
result.append(k)
return result
(版本三)使用集合
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return list(set(nums1) & set(nums2))
LeetCode 202.快乐数
文档讲解:代码随想录
视频讲解:
题目链接:. - 力扣(LeetCode)
编写一个算法来判断一个数 n
是不是快乐数。
「快乐数」 定义为:
- 对于一个正整数,每一次将该数替换为它每个位置上的数字的平方和。
- 然后重复这个过程直到这个数变为 1,也可能是 无限循环 但始终变不到 1。
- 如果这个过程 结果为 1,那么这个数就是快乐数。
如果 n
是 快乐数 就返回 true
;不是,则返回 false
。
示例 1:
输入:n = 19 输出:true 解释: 12 + 92 = 82 82 + 22 = 68 62 + 82 = 100 12 + 02 + 02 = 1
1、思路
- 当遇到快速判断一个元素是否出现集合里的时候,就要考虑哈希法了。
- 本题使用哈希法,来判断这个sum是否重复出现,如果重复了就是return false,否则一直找到sum为1为止
- 判断sum是否重复出现可以使用unordered_set
时间复杂度:O(logn)
空间复杂度:O(logn)
2、代码
(版本一)使用集合
class Solution:
def isHappy(self, n: int) -> bool:
record = set()
while n not in record:
record.add(n)
new_num = 0
n_str = str(n)
for i in n_str:
new_num+=int(i)**2
if new_num==1: return True
else: n = new_num
return False
(版本二)使用集合+精简
class Solution:
def isHappy(self, n: int) -> bool:
seen = set()
while n != 1:
n = sum(int(i) ** 2 for i in str(n))
if n in seen:
return False
seen.add(n)
return True
(版本三)使用数组
class Solution:
def isHappy(self, n: int) -> bool:
record = []
while n not in record:
record.append(n)
new_num = 0
n_str = str(n)
for i in n_str:
new_num+=int(i)**2
if new_num==1: return True
else: n = new_num
return False
(版本四)使用数组+精简
class Solution:
def isHappy(self, n: int) -> bool:
seen = []
while n != 1:
n = sum(int(i) ** 2 for i in str(n))
if n in seen:
return False
seen.append(n)
return True
LeetCode 1.两数之和
文档讲解:代码随想录
视频讲解:梦开始的地方,Leetcode:1.两数之和,学透哈希表,map使用有技巧!_哔哩哔哩_bilibili
题目链接:. - 力扣(LeetCode)
给定一个整数数组 nums
和一个整数目标值 target
,请你在该数组中找出 和为目标值 target
的那 两个 整数,并返回它们的数组下标。
你可以假设每种输入只会对应一个答案。但是,数组中同一个元素在答案里不能重复出现。
你可以按任意顺序返回答案。
示例 1:
输入:nums = [2,7,11,15], target = 9 输出:[0,1] 解释:因为 nums[0] + nums[1] == 9 ,返回 [0, 1] 。
1、思路
- 当需要查询一个元素是否出现过,或者一个元素是否在集合里时,想到用哈希法
- 本题不仅要知道元素有无遍历过,还要知道这个元素对应的下标,需要使用key value结构来存放,key来存元素,value来存下标,使用map正合适,map用来存放访问过的元素
- 本题不需要key有序,选择unordered_map效率更高
时间复杂度:O(n)
空间复杂度:O(n)
2、代码
(版本一)使用字典
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中
return []
(版本二)使用集合
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
#创建一个集合来存储我们目前看到的数字
seen = set()
for i, num in enumerate(nums):
complement = target - num
if complement in seen:
return [nums.index(complement), i]
seen.add(num)