在LeetCode上做了 383. 赎金信(一道简单hash题)之后,翻看官方题解时发现用了 Counter 类:
class Solution:def canConstruct(self, ransomNote: str, magazine: str) -> bool:if len(ransomNote) > len(magazine):return Falsereturn not collections.Counter(ransomNote) - collections.Counter(magazine)
查看定义可知:Counter 是 collections 模块的一个类,用于统计可哈希对象的出现次数。它的实例可以看作是一个字典,其中键是元素,值是元素的计数。
关于Counter的详细介绍我参考的这篇博客:Python collections模块之Counter()详解
这里介绍一下 Counter
的比较规则:
-
相加:两个
Counter
实例相加时,会将相同键的值相加,生成一个新的Counter
,其中包含所有键及其总计数。from collections import Counterc1 = Counter('abc') c2 = Counter('aab') result = c1 + c2 # result: Counter({'a': 3, 'b': 2, 'c': 1})
-
相减 (
-
):两个Counter
实例相减时,会将相同键的值相减,但如果某个键的结果为负数,则该键会被移除。例如:
from collections import Counterc1 = Counter('aab') c2 = Counter('aabb') result = c1 - c2 # result: Counter()
-
做比较:
Counter(a) <= Counter(b)
会检查Counter(a)
中的每个元素,确保它的计数不大于Counter(b)
中的对应元素的计数,如果满足返回True,否则返回False。也可以看作减法,如果Counter(a) - Counter(b)
得到的Counter
为空的(即False),那么原不等式成立。
回到官方题解的代码,首先判断二者长度,如果 len(ransomNote) > len(magazine)
直接返回 False
,然后比较 Counter(ransomNote) - Counter(magazine)
,注意这里要加一个 not
,因为 Counter
减法结果 False
表示的才是正确,返回 True
。
往下翻阅其他人的题解,也发现了用不等式实现的:
class Solution:def canConstruct(self, ransomNote: str, magazine: str) -> bool:return Counter(ransomNote) <= Counter(magazine)
注:LeetCode平台会自动导入常用的库,如
collections
模块。所以不需要显式地写import Counter
。