1.暴力枚举,试图找一个合适的整数i,看看这个整数能否被两个整数numberA和numberB同时整除。i从2开始累加,一直加到numberA和numberB中较小参数的一半。循环结束后,上一次找到的能够被两整数的最大i值,就是两数的最大公约数。
package 最大公约数; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int NumberA = sc.nextInt(); int NumberB = sc.nextInt(); System.out.println(gcd(NumberA,NumberB)); } //暴力枚举,试图找一个合适的整数i,看看这个整数能否被两个整数numberA和numberB同时整除。i从2开始累加, //一直加到numberA和numberB中较小参数的一半。循环结束后,上一次找到的能够被两整数的最大i值,就是两数的最大公约数。 private static int gcd(int numberA, int numberB) { int smallNumber = numberA<numberB ? numberA:numberB; int bigNumber = numberA<=numberB ? numberB:numberA; if(bigNumber%smallNumber==0) { return smallNumber; } int greatestCommonDivisor = 1; for(int i = 2; i <= smallNumber/2;i++) { if(numberA%i==0&&numberB%i==0) greatestCommonDivisor = i; } return greatestCommonDivisor; } }
缺点:当输入的两个数分别为100000和100001时,要进行循环10000/2-1 = 4999 次,效率跟不上。
2.辗转相除法
package 最大公约数; import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int NumberA = sc.nextInt(); int NumberB = sc.nextInt(); System.out.println(gcd(NumberA,NumberB)); } private static int gcd(int numberA, int numberB) { if(numberA%numberB==0) return numberB; else return gcd(numberB,numberA%numberB); }
3.更相减损术
import java.util.Scanner; public class Main { public static void main(String[] args) { Scanner sc = new Scanner(System.in); int NumberA = sc.nextInt(); int NumberB = sc.nextInt(); System.out.println(gcd(NumberA,NumberB)); } private static int gcd(int numberA, int numberB) { if(numberA == numberB) return numberA; if(numberA<numberB) return gcd(numberB-numberA,numberA); else return gcd(numberA-numberB,numberB); }
1.暴力枚举法:时间复杂度O(min(a,b));
2.辗转相除法:时间复杂度O(log(max(a,b)));
3.更相减损术:时间复杂度O(max(a,b));