383 赎金信
给你两个字符串:ransomNote 和 magazine ,判断 ransomNote 能不能由 magazine 里面的字符构成。
如果可以,返回 true ;否则返回 false 。
magazine 中的每个字符只能在 ransomNote 中使用一次。ransomNote 和 magazine 由小写英文字母组成
示例 1:
输入:ransomNote = “a”, magazine = “b”
输出:false
示例 2:
输入:ransomNote = “aa”, magazine = “ab”
输出:false
示例 3:
输入:ransomNote = “aa”, magazine = “aab”
输出:true
思路
这道题目和242.有效的字母异位词很像,242.有效的字母异位词 (opens new window)相当于求 字符串a 和 字符串b 是否可以相互组成 ,而这道题目是求 字符串a能否组成字符串b,而不用管字符串b 能不能组成字符串a。
两个需要注意的点:
- 第一点“为了不暴露赎金信字迹,要从杂志上搜索各个需要的字母,组成单词来表达意思” 这里说明杂志里面的字母不可重复使用。
- 第二点 “你可以假设两个字符串均只含有小写字母。” 说明只有小写字母,这一点很重要(说明可以用数组,然后采用空间换时间的策略,用一个长度为26的数组来记录)
数组
class Solution(object):
def canConstruct(self, ransomNote, magazine):
"""
:type ransomNote: str
:type magazine: str
:rtype: bool
"""
# 用两个数组来记录两个字符串中字符的出现个数 因为只有小写字母
r_list = [0]*26
m_list = [0]*26
for i in ransomNote:
r_list[ord(i)-ord('a')] += 1 # 每个字符出现次数
for i in magazine:
m_list[ord(i)-ord('a')] += 1 # 每个字符出现次数
return all(r_list[i] <= m_list[i] for i in range(26)) # 判断是否能组成 all这个很巧妙
使用deafaultdict
class Solution(object):
def canConstruct(self, ransomNote, magazine):
"""
:type ransomNote: str
:type magazine: str
:rtype: bool
"""
# 判断两个字符串中字符的出现次数
hasgmap = defaultdict(int) # 定义一个字典计数器
for i in magazine: # 因为是判断ransomNote是否能够由magazine中的字符组成
hasgmap[i] += 1
for i in ransomNote:
value = hasgmap.get(i)
if not value: # 注意这与 value==0 不一样 not value表示不存在这个键 获取不到值 就是None
return False # 遍历完之前就已经没有这个键了
else:
hasgmap[i] -= 1
return True