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

PHP实现Codewars的Integers: Recreation One算法超时优化求助

优化Codewars《整数趣味题一》的PHP代码以解决超时问题

问题描述

数字246的因数为1、246、2、123、3、82、6、41。将这些因数平方后得到:1、60516、4、15129、9、6724、36、1681。这些平方数的和为84100,而84100恰好是290的平方。

任务

找出m到n之间(1 ≤ m ≤ n,m和n为整数)所有满足「其因数平方和本身是平方数」的整数。返回一个包含子数组的数组,每个子数组包含两个元素:第一个是符合条件的整数,第二个是其因数平方和。

示例

list_squared(1, 250) → [[1, 1], [42, 2500], [246, 84100]]
list_squared(42, 250) → [[42, 2500], [246, 84100]]

问题与原始代码

我的代码能通过基础测试,但提交时超时。我知道嵌套for循环导致时间复杂度太差,但不知道怎么改。请问如何优化代码提升速度?

原始代码:

function listSquared($m, $n) {
    $results = [];

    for ($i = $m; $i <= $n; $i++) {

        $squared_divisors = [];

        for ($num = 1; $num <= $i; $num++) {
            if ($i % $num === 0) {
                array_push($squared_divisors, ($num * $num));
            }
        }

        $sum = array_sum($squared_divisors);
        $sqrt_sum = sqrt($sum);

        if ((int)$sqrt_sum == $sqrt_sum) {
            array_push($results, [$i, $sum]);
        }
    }

    return $results;
}

优化方案

核心优化思路

原始代码的内层循环遍历到$i,时间复杂度为O(n²),这是超时的根本原因。优化方向集中在减少因数查找的遍历范围和降低不必要的操作开销。

1. 缩小因数查找范围

找因数无需遍历到$i,只需遍历到sqrt($i)即可:

  • 若num是$i的因数,则$i / num也必然是$i的因数
  • 这样内层循环的时间复杂度从O(n)降至O(√n),整体效率大幅提升

2. 直接累加平方和,避免数组操作

不需要将所有因数平方值存入数组再求和,直接在遍历过程中累加,减少数组的创建、插入和求和开销。

3. 避免平方根重复计算

提前计算sqrt($i)并赋值给变量,避免循环中重复调用sqrt()函数。

优化后的代码

function listSquared($m, $n) {
    $results = [];

    for ($i = $m; $i <= $n; $i++) {
        $sum = 0;
        $sqrtI = sqrt($i);
        
        for ($num = 1; $num <= $sqrtI; $num++) {
            if ($i % $num === 0) {
                $sum += $num * $num;
                $pair = $i / $num;
                // 当因数是平方根时,避免重复累加(如4的因数2,只加一次平方)
                if ($pair !== $num) {
                    $sum += $pair * $pair;
                }
            }
        }

        $sqrtSum = sqrt($sum);
        if ((int)$sqrtSum === $sqrtSum) {
            $results[] = [$i, $sum];
        }
    }

    return $results;
}

额外优化建议

如果函数会被多次调用,或者处理范围存在重复数值,可以添加缓存机制(比如用静态数组存储已计算过的数的平方和),避免重复计算,进一步提升效率。


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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.19 14:23:14