problem
Given an arbitrary ransom note string and another string containing letters from all the magazines, write a function that will return true if the ransom note can be constructed from the magazines ; otherwise, it will return false.
Each letter in the magazine string can only be used once in your ransom note.
Note:
You may assume that both strings contain only lowercase letters.
canConstruct("a", "b") -> false
canConstruct("aa", "ab") -> false
canConstruct("aa", "aab") -> true
用报纸拼字符串的问题,后面的参数为报纸,前面的为待拼字符串
solution
- 使用collections.Counter
from collections import Counter
class Solution(object):
def canConstruct(self, ransomNote, magazine):
"""
:type ransomNote: str
:type magazine: str
:rtype: bool
"""
if ransomNote:
target = Counter(ransomNote+'a')
resource = Counter(magazine+'a')
return all([True if resource[i]- target[i] >= 0 else False for i in target])
else:
return True
discuss里有一个更精简的写法.同样的问题是效率不高(后20%)
反过来减,如果不能完全包含则不为空,反之为空
利用not 把返回值空/非空,转换为True/False
def canConstruct(self, ransomNote, magazine):
return not collections.Counter(ransomNote) - collections.Counter(magazine)
discuss
很好理解,效率高一些(可能是in的判断减少了很多无效的比较)
magazine会不断变化剔除用过的元素个体
def canConstruct(self, ransomNote, magazine):
"""
:type ransomNote: str
:type magazine: str
:rtype: bool
"""
for element in ransomNote:
if element not in magazine:
return False
else:
i = magazine.find(element)
magazine = magazine[:i] + magazine[i+1:]
return True