一、赎金信
易错:注意magazine中的字符只能再ransomNote使用一次,所以考虑重复字符问题,即需要计数。
class Solution:
def canConstruct(self, ransomNote: str, magazine: str) -> bool:
map={}
for char in magazine:
if char in map:
map[char]+=1
else:
map[char]=1
for char in ransomNote:
if char in map:
map[char]-=1
if map[char]<0:
return False
else:
return False
return True
二、同构字符串
注意:提示给的t 和s 长度相同,和第三题‘单词规律’做区分。
易错:
要考虑到做双向映射,不能只做单向映射
class Solution:
def isIsomorphic(self, s: str, t: str) -> bool:
map_s={}
map_t={}
for (char_s,char_t) in zip(s,t):
if char_s in map_s:
if map_s[char_s] != char_t:
return False
if char_t in map_t:
if map_t[char_t] != char_s:
return False
else:
map_s[char_s]=char_t
map_t[char_t]=char_s
return True
三、单词规律
易错:
1. 要和上题“同构字符串”区分,pattern 和 s 虽然都是字符串但结构不同,我们需要从s中提取出单词,重新组成列表再做双向映射
2. 可能出现单个单词映射没问题,但是数量不对等的情况。例如:pattern='aaa',s='ha ha ha ha'
知识点1:怎么从句子形式的字符串提取单词?
答:
word=str.split()
单词分开以后组成列表形式。
知识点2:打包zip后提取(for (char, word) in zip(pattern, words):)如果pattern和words长度不相等,会出现什么情况?
答:
zip()
将会停止在最短的可迭代对象的末尾,丢弃较长可迭代对象的额外元素。
class Solution:
def wordPattern(self, pattern: str, s: str) -> bool:
words=s.split()
map_pattern={}
map_words={}
if len(words) != len(pattern):
return False
for (char,word) in zip(pattern,words):
if char in map_pattern:
if map_pattern[char]!=word:
return False
if word in map_words:
if map_words[word] !=char:
return False
else:
map_pattern[char]=word
map_words[word]=char
return True
四、有效的字母异位词
易错:
没有考虑t是s子类的情况,即s='aaaa',b='a'
class Solution:
def isAnagram(self, s: str, t: str) -> bool:
if len(s) != len(t):
return False
map={}
for char in s:
if char in map:
map[char]+=1
else:
map[char]=1
for char in t:
if char in map:
map[char]-=1
if map[char]<0:
return False
else:
return False
return True
五、字母异位词分组(三的进阶)
易错:
map中的value值是列表;
注意输出是列表嵌套列表;
知识点1:字符串中的单词怎么对字母排序生成新字母?
答:
''.join(sorted(word))
- ''引号表示每个字母中间的分隔符号,这里为空,即不分割。
- sorted是对字符串排序,生成单独的字符
知识点2:字典怎么对指定键的value值进行添加?
答:这里其实是去除值(map[same_str]),这个值是列表形式,所以列表添加内容是.append()
知识点3:怎么讲一个元素表示成列表?
答:list(元素)
class Solution:
def groupAnagrams(self, strs: List[str]) -> List[List[str]]:
map={}
for str in strs:
same_str=''.join(sorted(str))
if same_str in map:
map[same_str].append(str)
else:
map[same_str]=[str]
return list(map.values())
六、两数之和
易错:
1. 注意map中key和value对应num和index
2. 不能使用两次相同的元素,即值需要更新
class Solution:
def twoSum(self, nums: List[int], target: int) -> List[int]:
map={}
for index,num in enumerate(nums):
complement=target-num
if complement in map:
return index,map[complement]
map[num]=index
return False
七、快乐数
易错:
1. 思路很难想到。需要用哈希表去判断有没有无限循环。
2. 创建类的成员函数的时候,传入参数的括号中一定要加self.
3. 注意return
知识点1:怎么将整数的每个数字单独提取出来?
答案:先取余再整除10
class Solution:
def isHappy(self, n: int) -> bool:
my_set=set()
while n !=1 and n not in my_set:
my_set.add(n)
n=self.get_sum_squre(n)
return n==1
def get_sum_squre(self,n):
sum =0
while n>0:
digit=n%10
sum+=digit*digit
n=n//10
return sum
八、存在重复元素Ⅱ
易错:
不管两个条件是否都满足,如果有重复key这个时候都需要更新map[num]的value值,而不是用if...else...,因为条件是小于等于,又是按排序遍历,所以前面条件没满足就直接pass掉,更新序列更大的值。
class Solution:
def containsNearbyDuplicate(self, nums: List[int], k: int) -> bool:
map={}
for index,num in enumerate(nums):
if num in map:
if index-map[num]<=k:
return True
else:
map[num]=index
else:
map[num]=index
return False
九、最长连续序列
易错:
直接用数组创建set,有没有重复元素没关系;
遍历的是set不是数组;
循环判断条件!
class Solution:
def longestConsecutive(self, nums: List[int]) -> int:
my_set=set(nums)
max_len=0
for num in nums:
if num-1 not in my_set:
current_num=num
count=1
while current_num+1 in my_set:
count+=1
current_num+=1
max_len=max(max_len,count)
return max_len