本文介绍一种时间复杂度更优的方法,通过从 2 开始向上遍历至 √n,动态记录小于等于 √n 的最大因数,并结合其配对因数(n ÷ 该因数),最终比较二者与 √n 的距离,准确返回最接近平方根的正因数。
要找到一个正整数 n 的最接近其平方根的正因数,关键在于理解:若 d 是 n 的因数,则 n/d 必然也是;且这两者关于 √n 对称——一个小于等于 √n,另一个大于等于 √n(当 d ≠ √n 时)。因此,只需遍历到 ⌊√n⌋,就能捕获所有“左半边”因数,再通过配对快速获得“右半边”,最后比较距离即可。
以下是一个高效、健壮的 Java 实现:
public static int closestDivisor(int n) {
if (n <= 0) throw new IllegalArgumentException("n must be positive");
if (n == 1) return 1;
int sqrt = (int) Math.sqrt(n);
int candidateLower = 1; // 最大小于等于 √n 的因数(初始为 1,因为 1 总是因数)
// 只需检查 2 到 sqrt(含)
for (int i = 2; i <= sqrt; i++) {
if (n % i == 0) {
candidateLower = i;
// 若 i == √n(即 n 为完全平方数),直接返回——此时 i 就是最优解
if (i * i == n) {
return i;
}
}
}
// 得到两个候选:candidateLower 和 candidateUpper = n / candidateLower
int candidateUpper = n / candidateLower;
// 比较 |candidateLower - √n| 与 |candidateUpper - √n|
double root = Math.sqrt(n);
double diffLower = Math.abs(candidateLower - root);
double diffUpper = Math.abs(candidateUpper - root);
return diffLower <= diffUpper ? candidateLower : candidateUpper;
}✅ 示例验证:
7−6.48|=0.52 → 返回 6。 ⚠️ 注意事项:
该方法兼顾正确性、效率与可读性,适用于算法题、数学工具函数或性能敏感的因数分析场景。