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

如何优化将输入x拆分为两个幂之和的求解算法?

嘿,我来给你捋捋怎么优化这个判断x = i^m + j^n(i,j≥0,n,m>1)的算法——之前速度慢大概率是因为没把控好枚举范围,做了太多无用功。咱们从几个核心方向入手优化:

1. 大幅缩小枚举的边界范围

这是提升速度最关键的一步,原来的慢往往是因为没意识到很多枚举是完全没必要的:

  • 首先,对于任意k^p(p>1),它的取值上限就是x(毕竟jn≥0,所以im最多等于x)。更精准的是,对每个指数m>1,i的最大可能值是floor(x^(1/m))——比如x=100,m=3时i最大只能是4(4³=64≤100,5³=125就超了),直接砍掉了大量无效的i值。
  • 其次,指数m的范围也不用无限大:当m>log₂(x)时,2m已经大于x了,这时候i只能是0或1(i≥2的话im≥2m>x),对应的im就是0或1,这时候只需要检查x或x-1是不是某个数的n次方(n>1)就行,不用再枚举i了。
2. 预计算+集合查询,替代双重枚举

与其反复计算im和jn,不如先把所有≤x的完美幂(即满足k^p,p>1、k≥0的数)都算出来,存到一个集合里。这样问题就简化成:判断x是否能拆成集合中两个数的和(允许重复,比如1+1=2)。

  • 预计算的时候要注意去重:比如0的任何次幂都是0,1的任何次幂都是1,只需要各存一次;对于k≥2,计算k²、k³…直到结果超过x,把这些值加入集合即可。
  • 集合的查询是O(1)的,所以遍历集合中的每个数s,检查x-s是否也在集合里,比原来的双重枚举效率高太多。
3. 提前终止不必要的计算

在枚举或检查过程中,一旦找到符合条件的组合,立刻返回结果,别做多余的工作:

  • 比如在预计算完集合后,只要找到一个s使得x-s在集合里,直接返回True,不用遍历完整个集合。
  • 判断一个数是否是完美幂时,也可以提前终止:比如先看它是不是0或1(这俩本身就是完美幂),然后计算它的平方根、立方根…直到根小于2,只要有一个根是整数且指数>1,就说明是完美幂,不用再继续算更高次的根了。
4. 特殊情况优先处理

先把一些简单的情况直接处理掉,不用走复杂流程:

  • 比如x=0:0=0²+0²,直接返回True;
  • x=1:1=0²+1²,返回True;
  • x=2:1²+1²=2,返回True;
  • x<0:因为i,j都是非负整数,所以x不可能是负数,直接返回False。
给你个优化后的伪代码参考
def is_sum_of_two_powers(x):
    if x < 0:
        return False
    # 处理特殊小值
    if x in {0, 1, 2}:
        return True
    
    power_set = set()
    # 添加0和1(避免重复计算它们的高次幂)
    power_set.add(0)
    power_set.add(1)
    
    # 计算k≥2的所有完美幂
    k = 2
    while True:
        k_sq = k * k
        if k_sq > x:
            break
        power_set.add(k_sq)
        # 计算更高次幂
        p = 3
        while True:
            k_pow = k ** p
            if k_pow > x:
                break
            power_set.add(k_pow)
            p += 1
        k += 1
    
    # 检查是否存在两个幂的和为x
    for s in power_set:
        complement = x - s
        if complement in power_set:
            return True
    return False

这个版本的效率比原来的暴力枚举高很多,尤其是当x很大的时候,能砍掉绝大多数无效计算。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.05.19 07:43:28