求解【最大公约数】:从暴力枚举到辗转相除法

你在刷题时是否遇到过超时困惑?明明测试样例通过却总卡在TLE(超时错误)?本文通过最大公约数(GCD)这一经典问题,带你用暴力枚举法直击算法效率瓶颈,再用欧几里得算法实现千倍性能飞跃。文末附赠LeetCode实战优化技巧,助你彻底掌握从理论到落地的完整优化链路!

目录

一、问题定义与应用场景

1.1 什么是最大公约数

二、求解方法

方法一:枚举-暴力求解

方法二:辗转相除法(欧几里得算法)

为什么辗转相除法更高效?

三、在线验证工具


一、问题定义与应用场景

1. 什么是最大公约数

  • 数学定义:两个整数的最大公共因数(能同时整除两个整数的最大正整数)

  • 示例:12和18的公约数为1,2,3,6 → GCD=6,表示为  gcd(12,18)=6

  • 应用场景:

        分数化简(3/9 → 1/3)

        密码学(RSA算法基础)

        图形学(屏幕宽高比适配)

二、求解方法


方法一:枚举-暴力求解


1.算法思路:

        逆向遍历法:首先找两数中的较小值,从两数较小值开始递减遍历,找到首个能同时整除的因子

        算法思路图解:    

int main()
{
	int x, y;
	scanf("%d %d", &x, &y);
	int min = x < y ? x : y;//找到最小值
    //倒序遍历
	for (int i = min; i > 0; i--)
	{
		if ((x % i == 0) && (y % i == 0))
		{
			printf("%d", i);
			break;
		}
	}
	return 0;
}

2.复杂度分析

  • 时间复杂度:O(min(a,b))

  • 空间复杂度:O(1)

  • 适合场景:小数据量(数值<1e4)


方法二:辗转相除法(欧几里得算法)


1.数学原理证明

        定理:gcd(a,b) = gcd(b, a mod b) 

        递归推导:gcd(48, 18) = gcd(18, 12) 

                                             = gcd(12, 6)

                                             = gcd(6, 0) 

                                             = 6

int main()
{
	int m, n;
	scanf("%d %d", &m, &n);
	int k = 0;
	while (k = m % n) //当余数为0时终止
	{
		m = n;
		n = k;
	}
	printf("%d", n);
	return 0;
}

说明:要求 m 和 n 的最大公约数,就让 m % n,若余数 k 不为0,就把 n 的值赋给 m ,k 的值赋给 n ,以此类推,直到余数为 0 ,最后 n 就是要找的最大公约数

2.复杂度对比

算法平均时间复杂度最坏情况
暴力枚举O(n)O(n)
辗转相除法O(log n)O(log n)

为什么辗转相除法更高效?

        数学解释:每次迭代至少减少一半数值(斐波那契数列衰减)

三、在线验证工具

1979. 找出数组的最大公约数 - 力扣(LeetCode)

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值