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

求数组中恰好被n-1个元素整除的最小M:代码问题排查

问题需求

找到最小的数M,使其能被输入数组中恰好n-1个元素整除(n为数组长度),若不存在则返回-1。

  • 样例1:数组[2,3,5],答案为6,因6可被2和3整除(恰好2个元素,n-1=3-1=2)。
  • 样例2:数组[2,3,6],答案为-1,因无法找到符合条件的M(排除任意一个元素后的最小公倍数都会被第三个元素整除)。
用户代码的问题

当前代码逻辑是取数组前n-1个元素相乘并返回,存在以下核心问题:

  1. 未考虑最小公倍数,直接乘积不是最优解
    比如数组[4,6,8],排除最后一个元素8后,剩余元素的最小公倍数是12(而非乘积24),12能被4和6整除,且不能被8整除,是符合要求的最小M。但用户代码返回24,不是正确的最小解。
  2. 未校验结果是否满足“恰好n-1个元素整除”的条件
    以样例2[2,3,6]为例,用户代码返回2*3=6,但6能被数组中所有3个元素整除,不符合“恰好n-1个”的要求,此时应返回-1,但代码未做判断。
  3. 未遍历所有可能的排除情况
    代码只排除了最后一个元素,忽略了排除数组中其他元素的情况。比如数组[3,4,6],排除4时最小公倍数是6(能被3、6整除,不能被4整除),这才是最小M,但用户代码返回3*4=12,错过正确解。
  4. 整数溢出风险
    当数组元素较大或长度较长时,直接相乘会超出int类型的取值范围,导致结果错误。
正确解决思路
  1. 遍历数组中的每个元素,依次将其排除,计算剩余n-1个元素的最小公倍数(LCM)。
    • 最小公倍数计算依赖最大公约数(GCD):LCM(a,b) = a*b / GCD(a,b),多个元素的LCM可通过迭代计算两两的LCM得到。
  2. 对每个得到的LCM,检查它是否不能被被排除的元素整除,确保满足“恰好n-1个元素能整除”的条件。
  3. 收集所有符合条件的LCM,取其中的最小值;若没有符合条件的,返回-1。
修正后的代码示例
public int process(int[] arr) {
    int n = arr.length;
    if (n <= 1) {
        return -1; // 数组长度<=1时,n-1无意义
    }
    int minM = Integer.MAX_VALUE;
    // 遍历每个要排除的元素
    for (int excludeIdx = 0; excludeIdx < n; excludeIdx++) {
        int currentLCM = 1;
        boolean overflow = false;
        // 计算剩余元素的LCM
        for (int i = 0; i < n; i++) {
            if (i == excludeIdx) continue;
            try {
                currentLCM = lcm(currentLCM, arr[i]);
            } catch (ArithmeticException e) {
                overflow = true;
                break;
            }
        }
        if (overflow) continue;
        // 检查当前LCM是否不能被排除的元素整除
        if (currentLCM % arr[excludeIdx] != 0) {
            if (currentLCM < minM) {
                minM = currentLCM;
            }
        }
    }
    return minM == Integer.MAX_VALUE ? -1 : minM;
}

// 计算最大公约数(GCD)
private int gcd(int a, int b) {
    while (b != 0) {
        int temp = b;
        b = a % b;
        a = temp;
    }
    return a;
}

// 计算最小公倍数(LCM),处理溢出
private int lcm(int a, int b) {
    if (a == 0 || b == 0) return 0;
    int gcdVal = gcd(a, b);
    // 先除法再乘法避免溢出
    return Math.multiplyExact(a / gcdVal, b);
}

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 02:40:31