面试题:求两个数的最大公约数

  • 暴力破解

  • 辗转相除法,欧几里得算法

  • 更相减损术

  • 位移运算混合版

  • 1、暴力破解,效率低下,如果求1000,10001,要循环1000/2 = 500次 时间复杂度O(n)

function getMaxCommonDivisor(a, b) {
    let big = a > b ? a : b
    let small = a < b ? a : b
    if (big % small === 0) {
        return small;
    }
    for (let i = small / 2; i > 1; i--) {
        if (small % i === 0 && big % i === 0) {
            return i;
        }
    }
    return 1;
}

console.log(getMaxCommonDivisor(21, 14));
console.log(getMaxCommonDivisor(21, 12));
  • 2、辗转相除法,欧几里得算法
  • 两个正整数a和b(a>b),它们的最大公约数等于a除以b的余数和b之间的最大公约数。
function getMaxCommonDivisor2(a, b) {
    let big = a > b ? a : b
    let small = a < b ? a : b
    if (big % small === 0) {
        return small;
    }
    console.log('big:' + big + ',small:' + small)
    return getMaxCommonDivisor2(big % small, small)
}
console.log(getMaxCommonDivisor2(21, 14));
console.log(getMaxCommonDivisor2(21, 12));
  • 3、更相减损术:两个正整数a和b(a>b),它们的最大公约数等于a-b的差值c和较小数b的最大公约数 时间复杂度O(log(n)),数据较大时性能低.
function getMaxCommonDivisor3(a, b) {
    if (a === b) {
        return a;
    }
    let big = a > b ? a : b
    let small = a < b ? a : b

    console.log('big:' + big + ',small:' + small)
    return getMaxCommonDivisor3(big - small, small)
}
console.log(getMaxCommonDivisor3(1232, 13144));
console.log(getMaxCommonDivisor3(21, 12));
  • 4、优化版:辗转相除法 和 更相减损术 相结合,位移运算 时间复杂度O(log(n))
function getMaxCommonDivisor4(a, b) {
    if (a === b) {
        return a;
    }
    console.log('a:' + (a) + ',b:' + (b));
    console.log('a:' + (a & 1) + ',b:' + (b & 1));

    // 偶数时位移运算
    if ((a & 1 === 0) && (b & 1 === 0)) {
        return getMaxCommonDivisor4(a >> 1, b >> 1) << 1;
    } else if ((a & 1) === 0 && (b & 1) !== 0) {
        return getMaxCommonDivisor4(a >> 1, b);
    } else if ((a & 1) !== 0 && (b & 1) === 0) {
        return getMaxCommonDivisor4(a, b >> 1);
    } else {
        let big = a > b ? a : b;
        let small = a < b ? a : b;

        return getMaxCommonDivisor4(big - small, small)
    }
}
console.log(getMaxCommonDivisor4(1232, 13144));
console.log(getMaxCommonDivisor4(21, 12));
原文地址:https://www.cnblogs.com/songliquan/p/13164378.html