题意整理
- 输入整数a和b。
- 求a和b的最大公约数。
方法一(暴力法)
1.解题思路
由于是a和b的最大公约数,那么它的范围一定在1到 之间,我们逆序遍历这个区间,找到能同时被a和b整除的数即可。
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 求出a、b的最大公约数。
* @param a int
* @param b int
* @return int
*/
public int gcd (int a, int b) {
// 首先求出a和b中的较小者
int min=Math.min(a,b);
//最大公约数一定在1到较小者之间
for(int i=min;i>=1;i--){
//如果同时被a,b整除,直接返回
if(a%i==0&&b%i==0){
return i;
}
}
return 1;
}
} 3.复杂度分析
- 时间复杂度:假设a和b的较小者为n,最坏情况下需要遍历n次,所以时间复杂度是
。
- 空间复杂度:需要额外常数级别的内存空间,所以空间复杂度为
。
方法二(递归)
1.解题思路
- 递归终止条件:余数mod为0,此时b为最大公约数。
- 每一层递归传递什么:将a替换为b,b替换为余数mod。
- 每一层递归返回什么:当前层的余数。
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 求出a、b的最大公约数。
* @param a int
* @param b int
* @return int
*/
public int gcd (int a, int b) {
int mod=a%b;
//递归终止条件
if(mod==0){
return b;
}
//只要递归没终止,将a换为b,b换为余数
return gcd(b,mod);
}
} 3.复杂度分析
- 时间复杂度:假设最终得到的最大公约数为d,a和b的较小者为n,我们把每次得到的余数按照逆序进行排列,那么它必然是
的形式,其中
,由于
可以知道这个数列的增长速度比斐波那契数列快,而斐波那契数列是呈指数增长的,所以时间复杂度是
。
- 空间复杂度:需要额外深度为
的递归栈,所以空间复杂度为
。
方法三(迭代)
1.解题思路
迭代的思路和递归相同,只是用变量来记录每一次替换的值。
动图展示:
2.代码实现
import java.util.*;
public class Solution {
/**
* 代码中的类名、方法名、参数名已经指定,请勿修改,直接返回方法规定的值即可
*
* 求出a、b的最大公约数。
* @param a int
* @param b int
* @return int
*/
public int gcd (int a, int b) {
//只要b不为0,就一直替换
while(b!=0){
//a替换为b,b替换为余数
int mod=a%b;
a=b;
b=mod;
}
//a记录的是变为0之前的那个余数
return a;
}
} 3.复杂度分析
- 时间复杂度:遍历次数和方法二递归的次数一致,所以时间复杂度是
。
- 空间复杂度:需要额外常数级别的空间,所以空间复杂度为
。

京公网安备 11010502036488号