242.有效的字母异位词
给定两个字符串
s
和t
,若s
和t
中每个字符出现的次数都相同,则互为字母异位词。
由于要记录字符出现的次数,给出两种记数方式:字典和列表
字典大家都非常熟悉,字符作为 key,构建位置映射,并对应一个 val。
这样我们就能记录每个字符出现的次数,最后遍历 s 和 t,对比两个字典即可。
列表并没有这种结构,如何构建字符和位置的对应关系呢?
使用字符的 ASCII 码值来表示他们在列表中的 index。例如,
a
映射到 index0
,b
映射到 index1
,以此类推,直到z
映射到 index25
。
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
#构建字典
countS, countT = {}, {}
# 遍历字符串
for char in s:
if char in countS:
countS[char] += 1
else:
countS[char] = 1
for char in t:
if char in countT:
countT[char] += 1
else:
countT[char] = 1
# 对比字典
return countS == countT
# 时间复杂度:
# O(n)
# 空间复杂度:
# O(1)
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
# 构建列表
count = [0] * 26
# 遍历 s,在对应位置上记数 +1
for char in s:
index = ord(char) - ord('a')
count[index] += 1
# 遍历 t,在对应位置上记数 -1
for char in t:
index = ord(char) - ord('a')
count[index] -= 1
# 如果互为字母异位词,则列表每个元素都应该为0
for i in count:
if i != 0:
return False
return True
# 时间复杂度:
# O(n)
# 空间复杂度:
# O(1)
349. 两个数组的交集
此处提供两个思路:
1. 内置函数,效率并不低
2. 双指针,优化空间复杂度
双指针思路:现将列表排序,接着分别定义一个指针指向列表首位,每次对比指针所指元素,如果相等则放入事先定义的 set。
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 内置函数
# set给两列表去重
set1 = set(nums1)
set2 = set(nums2)
# 求出交集
return list(set1 & set2)
# 时间复杂度:
# O(n)
# 空间复杂度:
# O(n)
class Solution:
def intersection(self, nums1: List[int], nums2: List[int]) -> List[int]:
# 双指针
nums1.sort()
nums2.sort()
index1, index2 = 0, 0
res = set()
while index1 < len(nums1) and index2 < len(nums2):
if nums1[index1] < nums2[index2]:
index1 += 1
elif nums1[index1] > nums2[index2]:
index2 += 1
else:
res.add(nums1[index1])
index1 += 1
index2 += 1
return list(res)
# 时间复杂度:
# O(n)
# 空间复杂度:
# O(1)
202. 快乐数
判断是否为快乐数时,在计算各位数平方和的循环中,有以下两个观察:
1. 某平方和重复出现,则说明此数字会无限循环,一定不是快乐数2. 如果平方和为 1,则说明为快乐数
class Solution:
def isHappy(self, n: int) -> bool:
def get_next_number(number):
return sum(int(i) **2 for i in str(number))
seen_numbers = []
while n not in seen_numbers:
if n == 1:
return True
else:
seen_numbers.append(n)
n = get_next_number(n)
return False
1. 两数之和
暴力:双层for循环遍历所有的情况
哈希法:通过一次遍历数组,对于每个元素
x
,检查target - x
是否已经在之前遍历的元素中出现过(即是否已存在于哈希表中)。如果存在,那么就找到了一对符合条件的元素,并可以直接返回它们的下标。这种方法的时间复杂度可以降低到 O(n)
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]
# 时间复杂度:
# O(n²)
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
# 创建字典记录已遍历元素,key为元素值,val为索引
seen = {}
for index, num in enumerate(nums):
# 对于每个遍历的元素,在seen中寻找其补数是否已被遍历过
complement = target - num
if complement in seen:
return [seen[complement], index]
else: seen[num] = index
# 时间复杂度:
# O(n)