
本文讲解如何用python高效统计目标字符串的所有不重复排列在主字符串中作为子串出现的次数,重点解决因重复字符导致itertools.permutations生成冗余排列而引发的计数错误。
在处理“统计某字符串所有不重复排列在另一字符串中作为子串出现次数”的问题时,一个常见误区是直接使用 itertools.permutations(N) 并转为列表进行遍历。例如,当 N = "aab" 时,permutations("aab") 会生成 6 个元组(因为 3! = 6),但实际只有 aab、aba、baa 这 3 个语义不同的字符串——其余是因两个 'a' 位置互换产生的重复排列。若不 deduplicate,就会对同一有效排列多次计数,导致结果偏高(如示例中输出 4 而非期望的 2)。
✅ 正确做法是:将 permutations(N) 的结果转为 set,利用集合自动去重的特性,确保每个唯一排列只被处理一次:
from itertools import permutations
N = input().strip() # 不需要 str(input()),input() 默认返回字符串
H = input().strip()
# 生成所有不重复的排列(去重关键步骤)
unique_perms = set(permutations(N))
# 统计其中有多少个排列作为子串出现在 H 中
count = 0
for p in unique_perms:
candidate = ''.join(p)
if candidate in H: # Python 的 in 操作对子串查找是高效的(底层为 Boyer-Moore 优化)
count += 1
print(count)更简洁的写法(推荐用于竞赛或代码精简场景):
from itertools import permutations N, H = input().strip(), input().strip() count = sum(1 for p in set(permutations(N)) if ''.join(p) in H) print(count)
⚠️ 注意事项:
- 切勿用 str 作变量名:原代码中 str = "".join(perm[i]) 覆盖了内置类型 str,可能导致后续代码异常(如无法调用 str(42))。应使用 s、substring 或 candidate 等语义化名称。
- 时间复杂度警示:该解法时间复杂度为 O(|N|! × |N| + |N|! × |H|),仅适用于 |N| ≤ 8 的小规模输入。若 N 较长(如 > 10),需改用滑动窗口 + 字符频次哈希(如 Counter)的线性算法,避免生成全排列。
- 空字符串与边界情况:input().strip() 可预防首尾空格;若题目允许空串,需额外判断 if not N: print(0 if H else 1)。
综上,核心修复点就一个:用 set(permutations(N)) 替代 list(permutations(N)),辅以规范命名和健壮输入处理,即可准确求解“不重复排列子串计数”问题。










