双层循环中反复调用gcd性能差,应排序剪枝或改用单次遍历求全局gcd;lcm易溢出,需用long、先除后乘并加溢出检查。
双层循环里反复调用
会拖慢性能
Java 标准库没有内置
,很多人自己写个两数
函数后,直接在双层循环里对每对数字都算一遍——比如求一个数组中所有数对的最大公约数最大值。这看似直觉,但时间复杂度是 O(n² × log(min(a,b))),n=10⁴ 就可能超时。
实操建议:
立即学习
“
Java免费学习笔记(深入)
”;
Eclipse导入Android或其他的JAVA项目的正确方法 WORD版
本文档主要讲述的是Eclipse导入Android或其他的JAVA项目的正确方法;希望本文档会给有需要的朋友带来帮助;感兴趣的朋友可以过来看看
下载
先用
降序排列,最大公约数往往出现在大数之间,可提前
或剪枝
若目标是“整个数组的最大公约数”,根本不用双层循环——单次遍历调用
即可
避免在循环内重复创建对象或装箱,比如用
而非
做参数
容易溢出,尤其和双层循环叠加时
最小公倍数公式是
,但
在 int 范围内就极易溢出(比如两个接近 10⁵ 的数相乘就超 2³¹)。双层循环一跑,第一批结果就可能是负数或 0,后续
全乱套。
实操建议:
立即学习
“
Java免费学习笔记(深入)
”;
改用
计算
,且先除后乘:
如果业务允许近似或限定范围,加一层溢出检查:
不要在双层循环里无条件存所有
到集合——内存爆得比 CPU 快
嵌套循环变量命名和边界容易写反
写
导致重复计算同一对,非常常见。更隐蔽的是:当数组含 0 时,
应返回
,但自制函数若没处理,会进死循环或抛异常。
实操建议:
立即学习
“
Java免费学习笔记(深入)
”;
循环变量统一用
、
,别用
/
或
/
——增加认知负担
边界检查写成
立刻能发现逻辑错误
函数开头加
,别依赖递归自动收敛
双层循环本身不是问题,问题在于把数学定义直接硬套成代码结构。真正难的不是嵌套几层,而是想清楚:你要的到底是“某一对”的极值,还是“全体”的合成值——后者根本不需要双层。
gcdgcdgcdArrays.sort()breakgcd(gcd(gcd(a[0],a[1]),a[2]),...)intIntegerlcma * b / gcd(a, b)a * bgcdlonglcm(a / gcd(a, b)) * (long) bif (a > Integer.MAX_VALUE / b * gcd(a,b)) { /* 跳过或报错 */ }lcmfor (int i = 0; i 是常规操作,但实际手写时,j 从 0 开始、i 和 j 次序颠倒、漏掉 +1gcd(a, 0)abs(a)ijmnidx1idx2j 或 j == igcdif (b == 0) return Math.abs(a);