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

Codewars趣味题#159:中间排列Python代码优化求助——长字符串运行过慢

优化Codewars Simple Fun #159的middle_permutation函数

你的原方案问题在于生成所有排列再排序,当字符串长度为15时,排列数是15!(约1.3e12),完全超出计算和存储的能力范围,必须用数学方法直接构造中间排列,无需遍历所有可能。

核心思路

排列按字典序排序后,中间位置的排列可以通过阶乘计算直接推导每个位置的字符:

  1. 先将输入字符串按字典序排序(因为排列排序的基准是字典序)
  2. 计算总排列数的中间索引:(n! // 2) - 1(和你的原代码逻辑完全对齐)
  3. 逐个确定每个位置的字符:对于剩余的k个字符,每个字符对应k!种排列,通过中间索引除以k!得到当前要选的字符的索引,更新剩余索引为余数,重复直到所有字符选完

优化后的代码

import math

def middle_permutation(string):
    chars = sorted(string)
    n = len(chars)
    mid_index = (math.factorial(n) // 2) - 1
    result = []
    remaining = chars.copy()
    k = n - 1
    
    while remaining:
        fact = math.factorial(k)
        # 计算当前位置要选的字符索引
        idx = mid_index // fact
        result.append(remaining.pop(idx))
        # 更新剩余索引,处理下一个位置
        mid_index = mid_index % fact
        k -= 1
    
    return ''.join(result)

为什么这个方法高效

  • 时间复杂度为O(n²):每次从剩余列表中移除字符是O(n),循环n次,对于n=15来说可以瞬间完成
  • 空间复杂度为O(n):只需要存储剩余字符和结果,不需要生成任何排列

验证示例

  • 输入"abc":排序后为['a','b','c'],总排列数6,中间索引2。第一个字符选idx=2//2=1(即'b'),剩余索引0,剩余字符['a','c'],下一个字符选0//1=0(即'a'),最后选'c',结果为"bac",和原代码输出一致
  • 输入"abcd":总排列数24,中间索引11,最终会得到"bacd"(和原代码生成排序后第11个元素完全一致)

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.06 07:27:51