You need to enable JavaScript to run this app.
最新活动
大模型
产品
解决方案
定价
生态与合作
支持与服务
开发者
了解我们

求助:含重复字母的单词下字母变位词位置计算代码失效问题

解决含重复字母的单词排列位置计算问题

嘿,我完全懂你卡壳的点——你的代码在处理无重复字母的单词(比如car)时工作正常,但遇到像testbookkeeper这类有重复字母的单词就失效了,核心问题出在排列数的计算没有考虑重复字母的去重

问题根源分析

当单词里有重复字母时,比如caar,如果单纯用math.factorial(len(wlsort)-1)来计算以某个字母开头的排列数,会把重复的排列(比如交换两个a的位置)算成不同的情况,但实际上这些是同一个单词,所以需要对阶乘结果进行去重修正。

举个例子:caar剩余字母是['c','a','a','r'],当计算以第一个a开头的排列数时,剩下的字母是['c','a','r'],这时候排列数是3!没问题;但如果剩余字母是['a','a','c','r'],计算以c开头的排列数时,剩下的字母是['a','a','r'],实际唯一排列数应该是3!/(2!),而不是3!——因为两个a交换位置不会产生新单词。

解决思路与修改方案

我们需要做的是:

  • 维护剩余字母的频率统计,而不是单纯排序后遍历,这样能准确计算重复字母的数量。
  • 对于每个当前字符,遍历所有比它小的唯一字符,计算以该字符开头的唯一排列数,公式为:
    (剩余长度-1)! / (乘积:每个重复字母的出现次数的阶乘)
    
  • 累加这些排列数,然后移除当前字符,继续处理剩余单词。

下面是修改后的代码示例:

import math
from collections import Counter

def listPosition(word):
    count = 0
    chars = list(word)
    char_counts = Counter(chars)
    
    while chars:
        current_char = chars[0]
        # 遍历所有比当前字符小的唯一字符
        for c in sorted(char_counts.keys()):
            if c >= current_char:
                break
            # 临时复制计数器,减去当前要计算的字符c一次
            temp_counts = char_counts.copy()
            temp_counts[c] -= 1
            if temp_counts[c] == 0:
                del temp_counts[c]
            # 计算分子:(剩余长度-1)!
            numerator = math.factorial(len(chars)-1)
            # 计算分母:各重复字母的阶乘乘积
            denominator = 1
            for freq in temp_counts.values():
                denominator *= math.factorial(freq)
            # 累加唯一排列数
            count += numerator // denominator
        
        # 移除当前字符,更新计数器
        char_counts[current_char] -= 1
        if char_counts[current_char] == 0:
            del char_counts[current_char]
        chars.pop(0)
    
    return count + 1

代码解释

  1. Counter统计频率:用Counter来跟踪剩余每个字母的出现次数,比排序后找索引更高效,也能直接处理重复。
  2. 遍历更小的唯一字符:对排序后的唯一字符遍历,一旦遇到大于等于当前字符的就停止,避免无效计算。
  3. 计算唯一排列数:用(n-1)!除以各剩余字母频率的阶乘乘积,得到以该字符开头的所有唯一变位词数量。
  4. 更新状态:每次处理完当前字符后,更新计数器并移除该字符,继续处理剩余部分。

这样修改后,不管是无重复还是有重复字母的单词,都能准确计算出它在所有唯一变位词中的位置啦。

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

火山引擎 最新活动