题意整理

  • 输入整数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.复杂度分析

  • 时间复杂度:遍历次数和方法二递归的次数一致,所以时间复杂度是图片说明
  • 空间复杂度:需要额外常数级别的空间,所以空间复杂度为图片说明