意义
最大公约数和最小公倍数是数论的基石。
经常刷leetcode的同学应该见识到了很多标注数学分类的题目都有这两个的影子,
或者有类似这两个的思路。
最小公倍数
a = 2
b = 4
def lcm(a,b):
m = a
l = b
while(1):
if (m<l):
m+=a
else:
l+=b
if m == l:
break
return m
print(lcm(a,b))
循环跳步的方法求最小公倍数。可以想象成两个同学跳远。谁落后谁就一直跳。
而不是从啊,a,b中最大的数开始检验,那就是线性时间了。
我记得线性时间o(n)要追求log(n),或者是至少追求一个o(n/m)m为某个和题目相关的常量。
这一道题目不可以log(n)的。原因也很有趣
因为下界是两者中的较大值,上界是两者的乘积。这样就变成有限区间内求满足条件的某个点。二分查找自然就可以想到了。
但是二分查找的条件要求根据当前的区间就可以判定。可问题是最小公倍数在不在当前区间无法简单判定。不像一般意义上通过上下界(宏观特性)就可以判定。或者理解为没有在最大公倍数这个维度上排序好。
还有一种方法–可以先求两者的最大公约数,两个整数的乘积除以两个数的最大公约数即为两个数的最小公倍数。
最大公约数
辗转相除法,标准方法
## gcd
# gcd(a,b) = gcd(b,a mod b)
# 余数为零时,余数就是最大公约数
# 递归版本
def gcd(a,b):
# rep = -1
if (a>b):
m = a
l = b
else:
m = b
l = a
rep = m%l
if rep == 0:
return l
gcd(l,rep)
print(gcd(100,20))
# 迭代版本
def gcd1(a,b):
if a < b:
a,b=b,a # python可以这么写,有些语言不可以
res = a%b
while(res!=0):
a = b
b = res
return b
print(gcd1(100,20))