面试题:求两个数的最大公约数
-
暴力破解
-
辗转相除法,欧几里得算法
-
更相减损术
-
位移运算混合版
-
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));
本文来自博客园,作者:struggle_time,转载请注明原文链接:https://www.cnblogs.com/songliquan/p/13164378.html