小伙伴们共勉~
哈希表理论基础
1. 在 Python 中,hashset 通常指的是**set** 数据结构,set 是一个无序且不重复的元素集合,底层通过哈希表实现。因此,set 支持快速的查找、插入和删除操作,平均时间复杂度为 O(1)。
2. 快速查找:set 的查找时间复杂度为 O(1),而列表的查找时间复杂度为 O(n)。
3. 取交集
4. 差集:获取集合 A 中有而集合 B 中没有的元素。
5. 并集:获取两个集合的并集。
6. 对称差集:获取两个集合中不重复的元素。
set1 = {1, 2, 3}
set2 = {2, 3, 4}
intersection = set1 & set2 # 输出 {2, 3}
difference = set1.difference(set2) # 输出 {1}
union = set1.union(set2) # 输出 {1, 2, 3, 4}
symmetric_diff = set1.symmetric_difference(set2) # 输出 {1, 4}
242.有效的字母异位词
题目:两个词组成分是否完全一致
解题思路:储存str内容,判断组成内容和个数是否一致
• 时间复杂度:O(n),其中 n 是字符串的长度。我们遍历了两次字符串 s 和 t。
• 空间复杂度:O(1),因为字典的空间最多存储 26 个字母的计数。
# 这种做法先把s存起来,减去t里的字符
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t): return False
res = {}
for num in s:
res[num] = res.get(num,0) + 1
for num in t:
if num in res:
res[num] -=1
if res[num] == 0 :
del res[num]
else:
return False
return len(res) == 0
# 同理但code更简单一些
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
# 如果两个字符串的长度不相等,肯定不是异位词
if len(s) != len(t):
return False
# 使用两个字典分别统计两个字符串的字符出现次数
s_count = {}
t_count = {}
# 遍历字符串 s,记录每个字符的出现次数
for char in s:
s_count[char] = s_count.get(char, 0) + 1
# 遍历字符串 t,记录每个字符的出现次数
for char in t:
t_count[char] = t_count.get(char, 0) + 1
# 比较两个字典,如果相等,则是异位词
return s_count == t_count
解题思路:collections.Counter
• 解释:Counter(s) 会创建一个计数器对象,它会统计 s 中每个字符的出现次数。然后直接将两个计数器对象进行比较,如果它们相等,说明两个字符串是异位词。
• 时间复杂度:O(n),同样是遍历两次字符串。
• 空间复杂度:O(1),因为最多存储 26 个字母的计数。
from collections import Counter
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
return Counter(s) == Counter(t)
解题思路:
• 时间复杂度:O(nlog),纯纯暴力
return sorted(s) == sorted(t)
349. 两个数组的交集
解题思路:只考虑了相同的元素。
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
hash1 = {}
for char in nums1:
hash1[char] = hash1.get(char, 0) + 1
res = set()
for char in nums2:
if char in hash1:
res.add(char)
del hash1[char]
return list(res)
解题思路:set()应用
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
return list(set(nums1) & set(num2))
202. 快乐数
解题思路:先用一个func计算新值。判断是否已经存在,如果==1返回true,else加入到set里,若是在set里返回false
def isHappy(n: int) -> bool:
visited = set() # 用set记录已经访问过的数字,避免陷入循环
# 当 n 还未在 visited 中出现时,继续计算
while n not in visited:
if n == 1: # 如果 n 变成 1,返回 True
return True
visited.add(n) # 将当前数字加入到已访问集合中
n = sumOfSquare(n) # 计算当前数字的每位平方和
return False # 如果 n 进入了循环,返回 False
def sumOfSquare(n: int) -> int:
output = 0
while n:
new_digit = (n % 10) ** 2 # 取末位数字的平方
output += new_digit # 加到结果中
n = n // 10 # 去掉末位数字
return output
解题思路:可以把str(n)的每个元素直接平方求和
class Solution:
def isHappy(self, n: int) -> bool:
visited = set()
while n != 1:
n = sum(int(i) ** 2 for i in str(n))
if n in visited:
return False
visited.add(n)
return True
1. 两数之和
解题思路:两个组成的数一定会见到
• 时间复杂度:O(n),因为我们只需要遍历一次数组。
• 空间复杂度:O(n),因为我们需要额外的空间存储已访问过的元素。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
visited = set()
for i, num in enumerate(nums):
subtract = target - num
if subtract in visited:
return [nums.index(subtract), i]
visited.add(num)
解题思路:暴力
• 时间复杂度:O(n²),因为我们用了两个嵌套循环,每次都要检查所有可能的配对。
• 空间复杂度:O(1),没有额外的空间使用,除了返回的结果。
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
for i in range(len(nums)):
for j in range(i+1,len(nums)):
if nums[i] + nums[j] == target:
return [i,j]