Java求≤N的四个数最大LCM时遇算术异常及符号错误求助
问题分析与代码修正
核心错误点
GCD函数实现完全错误
原代码中gcd方法的递归逻辑写成了return gcd(y, x*y),这不符合欧几里得辗转相除法的规则,会导致递归时数值急剧膨胀,最终引发栈溢出或算术异常。正确的递归步骤应为gcd(y, x%y),同时需处理负数取绝对值。变量作用域问题
你修改代码时将c的定义放在if(b!=0)代码块内,导致后续return Math.max(c, num)无法访问该变量——变量c的作用域仅限于所在的if块,外部无法调用。未处理小N的边界场景
当N<4时,N-3会出现负数或0,直接计算会得到不合理的数值,需要单独处理这些情况。数值溢出风险
直接计算a*b可能会超出long类型的范围,计算LCM时应先做除法再乘法,避免溢出。
修正后的代码
class Solution { long maxLCM(int N) { // 处理小N的边界情况 if (N == 1) return 1; if (N == 2) return 2; if (N == 3) return 6; // 候选1:四个连续数的LCM long case1 = lcm(lcm(N, N-1), lcm(N-2, N-3)); // 候选2:取N、N-1后,再找两个与它们互质的数 long num = (long)N * (N-1); int count = 0; for (int i = N-2; i >= 1; i--) { if (gcd(num, i) == 1) { num *= i; count++; } if (count == 2) break; } return Math.max(case1, num); } // 正确的GCD实现(辗转相除法) long gcd(long x, long y) { x = Math.abs(x); y = Math.abs(y); if (y == 0) return x; return gcd(y, x % y); } // 计算LCM,先除后乘避免溢出 long lcm(long x, long y) { if (x == 0 || y == 0) return 0; return (x / gcd(x, y)) * y; } }
代码说明
- 边界处理:针对N=1、2、3的场景直接返回结果,避免无效计算。
- GCD/LCM方法:实现了正确的辗转相除法计算GCD,基于GCD推导LCM时先做除法再乘法,降低溢出风险。
- 双候选逻辑:同时计算两种组合的LCM并取最大值,确保覆盖所有可能的最优情况:
- 候选1:四个连续整数的LCM
- 候选2:取最大的两个数后,再补充两个与它们互质的数,保证LCM最大化
内容的提问来源于stack exchange,提问作者Neel Mishra
相关产品推荐
相关产品推荐

