crazycloudcc@blog:~/learn/least-common-multiple — zsh — 80×24
--:--:--···
crazycloudcc@blog:~/learn/least-common-multiple$ pwd
/home/crazycloudcc/blog/learn/least-common-multiple
> cd ./learn/least-common-multiple

算法 / 整除与倍数

最小公倍数 Least common multiple

沿两排倍数向前走,找到第一次共同的正落点。

同一数值必须落在同一横坐标上排是a的倍数,下排是b的倍数。空心0只是起点。实心落点为已经过的倍数,淡色虚线为尚未回放的跳步,最右侧标出第一个共同正倍数。从正倍数开始 · 0 不计入首次共同落点24a = 60+66+612+618+624b = 80+88+816+824两排共用数值刻度 · 改变输入时重新适配视野
gcd(6, 8) = 2lcm = 6 ÷ 2 × 8 = 24

24同时是6和8的倍数;前面没有共同的正落点。

回放按数值大小合并两排落点,同值只算一步;不是每步同时各跳一次。答案一直可读,动画只帮助观察。滑块可用方向键与 Home / End;窄屏图形可左右滚动。

为什么先除掉共同因子?

把共同尺度 d = 2 提出来:a = d × 3,b = d × 4,剩下的 3 和 4 互质。

a = 2 × 3b = 2 × 4lcm = 2 × 3 × 4 = 24

一般地,写成 a=dx、b=dy。dxy 同时是两数的倍数。若另一个正公倍数 M=ka 也被 b 整除,则 y 整除 kx;因为 x、y 互质,y 必须整除 k。所以每个正公倍数都包含 dxy,最小的就是它。这里用到互质整除引理,试几个例子本身不能替代证明。

// 本实验仅接受1到20的正整数
const a = 6, b = 8;
let x = a, y = b;
while (y !== 0) {
  const r = x % y;
  x = y; y = r;
}
const d = x; // 2
const result = (a / d) * b; // 24

先除后乘可减小中间值,但不保证任意大数都安全。本课范围内最大结果380;更大整数需要另定精度与溢出策略。绘制倍数的开销不计入上述求值算法。

三个数,不能直接照搬乘积公式

3、12、10 的 gcd 是1,乘积是360,但最小公倍数是60。两数恒等式不能直接变成“三数乘积 ÷ 三数gcd”。

正确做法是两两折叠:lcm(3,12)=12,再算 lcm(12,10)=12÷2×10=60。每个共同倍数先被12整除,再要求被10整除;没有丢掉任何共同倍数。图中仍只演示两个数。

看完图,带走这些结论

正整数a、b的最小公倍数,是同时被a和b整除的最小正整数。令d=gcd(a,b),则lcm(a,b)=(a/d)×b。6与8的倍数第一次在24相遇,因为gcd(6,8)=2,6÷2×8=24。

适用条件与边界

本课的LCM输入只讨论正整数;交互和同步代码仅接受1–20,结果不超过380。0只是数轴起点,不是正公倍数候选。负数、小数、空输入以及零输入的其他约定不在本课LCM输入范围内。两排必须使用同一数值刻度;输入改变后视野重新适配,不能跨输入比较像素长度。

始终保持的规律

两排同值落点拥有相同横坐标。令a=dx、b=dy且x、y互质,每个正公倍数都是dxy的正整数倍。

逐步例子

  1. 上排每次加6:6、12、18、24;下排每次加8:8、16、24。横坐标按数值对齐,不按第几个倍数对齐。24之前没有共同正落点,所以最小公倍数是24。
  2. 先求d=gcd(6,8)=2,写成6=2×3、8=2×4。3与4互质,把共同因子2保留一次,得到2×3×4=24,而不是直接乘成48。
  3. 一般地,设a=dx、b=dy,则x、y互质。dxy是两数的公倍数。若正公倍数M=ka也被b整除,就有y整除kx;由互质整除引理,y整除k,所以dxy整除M。它因此是最小的正公倍数。
  4. 相等时lcm(a,a)=a;一个数整除另一个时答案是较大数;互质时gcd=1,答案才等于两数乘积。1与任一正整数b的最小公倍数就是b。
  5. 三个数用两两折叠:lcm(3,12)=12,再算lcm(12,10)=60。3、12、10的gcd为1,乘积360不等于gcd×lcm的60;两数恒等式不能直接推广为三数乘积公式。

求值、绘图与精度

用欧几里得算法求GCD,再计算(a/d)×b;在单位成本整数算术模型下为O(1+log min(a,b))时间、O(1)额外空间。先除后乘减小中间值,但不保证任意大数都安全。实验范围内整数运算精确,最大结果为lcm(19,20)=380。枚举、排序回放落点与绘图另有开销,不是这个求值复杂度的一部分。

常见误区

  • 把0当最小值:0虽是两数的整数倍,但定义寻找的是最小正公倍数。
  • 直接相乘总是最小:ab是一个正公倍数,但a、b有共同因子时可能更大,例如6×8=48,而最小值24已经够用。
  • 按第k次跳跃对齐两排:6的第1个倍数与8的第1个倍数不在同一位置;要比较相同数值。
  • 把GCD和LCM混为一谈:GCD整除两数,LCM被两数整除。本课求的是后者。
  • 把三数乘积除以三数GCD:这不是普遍成立的公式;两两折叠仍然成立,因为每步保留相同的共同倍数集合。
  • 把图例当一般证明:两排落点帮助观察,最小性还要用互质整除引理或质因数指数给出推导。

自测与答案

8与12的最小公倍数是多少?7与7呢?3、12、10能否用360÷1直接得到最小公倍数?

gcd(8,12)=4,最小公倍数8÷4×12=24;相等的7与7得到7。三数不能这样直接套公式,正确折叠得到60,360只是一个更大的公倍数。

把最小公倍数用在通分里

  1. 通分为什么常用LCM?必须选最小的吗? 以同一个整体为1,1/6和1/8表示不同大小的一份,不能直接把份数相加。把整体分成24个等份:1/6=(1×4)/(6×4)=4/24,1/8=(1×3)/(8×3)=3/24;分子分母同乘同一个正整数,相当于乘4/4或3/3,值不变。于是4/24+3/24=(4+3)×(1/24)=7/24,相加的是同样大小的份数,每份仍为1/24。也可以用48作公分母,得到8/48+6/48=14/48=7/24。一般地,原分母b、d为正整数,任何同时被b、d整除的正整数M都可用来通分,因为M/b、M/d都是正整数;LCM只是在这些公倍数中最小的,并非必须选择它。通分是一种计算方法,不是分数能够相加的前提。
  2. 用LCM通分,结果一定最简吗? 不一定。即使原分数都已最简,1/6+1/3=1/6+2/6=3/6仍须约成1/2。原分数未约分时,先约分还可能用更小的公分母:2/6+2/8先化成1/3+1/4,就能用12通分;原分母6、8的LCM仍是24。通分与结果约分是不同步骤,约分可用GCD,详见下方前置课。这里是整数分母的文字应用;上方交互和同步代码仍只求两个1–20正整数的LCM,不计算分数加法。

延伸学习

GCD给出共同的因子,LCM给出共同的倍数。先理解取余如何保留公因数,再看为什么除去GCD能得到最小公倍数。

前置:用欧几里得算法求GCD

参考资料

纯文字 Markdown 阅读版

教学结构参考 AetherViz Master(MIT);原创原生 SVG,无外部图形脚本。

branch: mainposts: 12encoding: utf-8