You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何判断字符串/集合是否为另一者的子集?赎金信问题最优实现咨询

判断字符串/集合是否为另一子集的最佳方法(针对赎金信问题)

问题说明

给定两个字符串ransomNote和magazine,若ransomNote可由magazine中的字母构造而成(magazine中的每个字母在ransomNote中仅能使用一次),则返回true,否则返回false。想知道判断一个字符串/集合是否为另一个字符串/集合的子集的最佳方法是什么,有没有比手动统计每个字符更好的实现方式?现有实现代码如下:

def canConstruct(self, ransomNote: str, magazine: str) -> bool:
    c1, c2 = Counter(ransomNote), Counter(magazine)
    for letter in c1:
        if not (letter in c2 and c2[letter] >= c1[letter]):
            return False
    
    return True

优化实现方案

1. 极致简洁的Counter减法实现

你的现有代码已经利用了collections.Counter的特性,其实还能进一步简化——利用Counter的减法运算:当magazine的字符完全覆盖ransomNote的需求时,Counter(ransomNote) - Counter(magazine)会得到空的Counter对象,直接判断这个结果是否为空即可:

from collections import Counter

def canConstruct(self, ransomNote: str, magazine: str) -> bool:
    return not Counter(ransomNote) - Counter(magazine)

原理:Counter的减法会保留计数大于0的键值对,只有当magazine中每个字符的数量都不小于ransomNote时,减法结果才会是空,此时返回True。

2. 空间优化的数组统计实现

如果追求更低的空间复杂度(尤其是处理超大字符串时),可以用固定大小的数组来统计字符(因为只涉及小写字母),避免使用Counter的额外开销:

def canConstruct(self, ransomNote: str, magazine: str) -> bool:
    # 初始化26个字母的计数数组
    char_count = [0] * 26
    # 统计magazine中每个字符的数量
    for c in magazine:
        char_count[ord(c) - ord('a')] += 1
    # 遍历ransomNote,逐个减少计数
    for c in ransomNote:
        idx = ord(c) - ord('a')
        char_count[idx] -= 1
        # 若计数为负,说明magazine中该字符不足
        if char_count[idx] < 0:
            return False
    return True

这种方法的空间复杂度为O(1)(数组大小固定为26),在性能敏感场景下表现更优。

总结

  • 若优先考虑代码简洁性,Counter减法实现是最优选择,一行核心逻辑即可完成判断。
  • 若优先考虑空间效率,数组统计法更合适,无需导入额外模块,且内存开销极小。

内容的提问来源于stack exchange,提问作者Alec

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.31 06:21:37