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

给定正整数A求元素为3的幂且和为A的最短数组,是否有更优解法?

现有代码问题分析

你给出的原有实现逻辑是基于三进制分解,每一位的数值对应3^i的使用次数,在仅允许使用正3的幂的前提下,这个思路是对的,但存在两个可优化的问题:

  • 精度风险:使用Math.pow(3, i)计算3的幂,double类型的精度限制会导致大指数的计算结果出错。
  • 冗余循环:内层遍历j的逻辑可以简化,不需要额外变量控制循环次数。

更优实现(仅正3的幂场景)

优化思路:

  1. 预先累加计算3的幂,避免浮点数精度问题
  2. 去掉冗余的内层控制变量,直接按位数值添加对应次数的元素
  3. 不需要额外存储完整的三进制数组,可以边取余边处理,减少内存开销

优化后代码:

public static int[] getSolve(int A) {
    List<Integer> res = new ArrayList<>();
    int pow3 = 1; // 初始为3^0,每次循环乘3得到下一个幂
    while (A > 0) {
        int r = A % 3;
        for (int i = 0; i < r; i++) {
            res.add(pow3);
        }
        A = A / 3;
        pow3 *= 3;
    }
    return res.stream().mapToInt(Integer::intValue).toArray();
}

延伸:允许正负3的幂的最短实现

如果题目允许数组元素为负的3的幂(即可以用减法凑数),可以得到更短的数组。核心思路是三进制进位优化:遇到某一位余数为2时,将其转为-1并向上一位进1,这样每一位最多只有1个元素,数组长度最短。
比如A=8,原三进制是22,原有实现返回[1,1,3,3]长度为4,优化后用9 -1,返回[9, -1]长度仅为2。
对应实现代码:

public static int[] getSolveShortest(int A) {
    List<Integer> res = new ArrayList<>();
    int pow3 = 1;
    while (A != 0) {
        int r = A % 3;
        if (r == 2) {
            // 余数为2,转成-1,加1到高位
            res.add(-pow3);
            A += 1;
        } else if (r == 1) {
            res.add(pow3);
        }
        A /= 3;
        pow3 *= 3;
    }
    return res.stream().mapToInt(Integer::intValue).toArray();
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.09.28 23:06:00