题目的主要信息:

  • 求正整数a与正整数b的最小公倍数

方法一:暴力法

具体做法:

最小公倍数一定大于等于a与b中任意一个数,因此我们不妨从a开始往后找,遇到的第一个整除两个数的即是最小公倍数,可以输出,跳出循环。

#include<iostream>
using namespace std;

int main(){
    int a, b;
    while(cin >> a >> b){
        for(int i = a; ; i++){ //从a开始往后找
            if(i % a == 0 && i % b == 0){ //直到遇到第一个两个数的公倍数
                cout << i << endl;
                break;
            }
        }
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:O(ab)O(ab),最坏情况下最小公倍数为abab,需要遍历abaab-a
  • 空间复杂度:O(1)O(1),无额外空间

方法二:最小公因数法

具体做法:

首先我们要知道的一个知识:最小公倍数=两数相乘/两数的最大公约数,因为在两数乘积中最大公约数是多余的部分,可以约掉,使公倍数更小,约到最小就是除掉最大公约数。

而求最大公约数,我们可以用更相减损法,性质:两个数的最大公约数等于它们中较小的数和两数之差的最大公约数。

图片说明

用循环模拟上述过程即可以得到最大公约数,然后用两数乘积除以最大公约数得到最小公倍数。

#include<iostream>
using namespace std;

int gcd(int a, int b) { //更相减损法找最大公约数
    int temp = abs(a - b); //取差的绝对值 
    while(temp != 0){ //不断减去差的绝对值直到为0   
        a = b;
        b = temp;
        temp = abs(a - b);
    }
    return b;
}

int main(){
    int a, b;
    while(cin >> a >> b){
        cout << a * b / gcd(a, b) << endl; //乘积除以最大公因数
    }
    return 0;
}

复杂度分析:

  • 时间复杂度:最坏情况为O(max(m,n))O(max(m,n)),最坏一个一个减,全部减完
  • 空间复杂度:O(1)O(1),无额外空间