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

使用递归计算LCM时出现无限输出,该场景是否适合采用递归实现?

LCM递归实现方案及和循环实现的对比

原有代码的核心问题

你写的版本中每次递归是将当前的num1、num2直接翻倍,而非累加两数的初始值,也没有保留初始值作为参数,因此两数永远不会相等,只会无限递归直到栈溢出,自然跑不出你注释中的预期结果。

完全可以用递归实现LCM,主流有两种实现思路

思路1:基于你原本的步进逻辑修正

核心是新增参数保留两数的初始值,每次让较小的数累加对应初始值,直到两数相等:

const leastCommonMultiple = (a, b, originA = a, originB = b) => {
  if (a === b) return a
  return a < b 
    ? leastCommonMultiple(a + originA, b, originA, originB)
    : leastCommonMultiple(a, b + originB, originA, originB)
}
// 测试验证
console.log(leastCommonMultiple(4, 6)); // 12
console.log(leastCommonMultiple(3, 5)); // 15
console.log(leastCommonMultiple(2, 10)); // 10

该版本可正常跑出预期结果,但缺点也很明显:如果输入两个互质的大整数,递归深度会非常高,极易触发栈溢出。

思路2:基于GCD(最大公约数)实现,性能更优

根据数学公式 LCM(a,b) = |a*b| / GCD(a,b),我们可以先递归实现GCD的欧几里得算法,再推导LCM,该方案递归深度极低,完全不存在栈溢出风险:

// 递归实现欧几里得算法求最大公约数
const gcd = (a, b) => b === 0 ? a : gcd(b, a % b)
// 基于GCD求最小公倍数
const leastCommonMultiple = (a, b) => Math.abs(a * b) / gcd(a, b)

该方案是工业界的通用实现,性能远高于暴力步进方案。

递归和循环的选择建议

  • 若使用基于GCD的实现:递归写法更简洁易读,递归深度最多为log₂(min(a,b)),即便是10位以上的大整数,递归深度也不会超过40,完全不需要担心栈溢出问题,用递归完全合适。
  • 若使用暴力步进类的实现:递归存在栈溢出风险,这种场景更适合用循环实现,更推荐直接替换为GCD方案。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.02 16:39:00