当前位置: 首页 > article >正文

LeetCode 1492 n的第K个因子

寻找整数的第 K 个因子:算法解析与优化

问题描述

给定两个正整数 n 和 k,找到整数 n 的第 k 个因子(升序排列)。若因子数量不足 k,返回 -1

示例

  • 输入:n=12, k=3
    输出:3(因子:1, 2, 3, 4, 6, 12)
  • 输入:n=7, k=2
    输出:7(因子:1, 7)
  • 输入:n=4, k=3
    输出:-1(因子:1, 2, 4)

思路分析

方法一:暴力遍历(O (n))

  1. 遍历检查:从 1 到 n 遍历每个数,判断是否为因子。
  2. 计数匹配:维护因子计数器,找到第 k 个时返回。
代码实现(Java)
class Solution {
    public int kthFactor(int n, int k) {
        int count = 0;
        for (int i = 1; i <= n; i++) {
            if (n % i == 0) {
                count++;
                if (count == k) return i;
            }
        }
        return -1;
    }
}
复杂度分析
  • 时间复杂度:O (n),遍历所有可能的因子。
  • 空间复杂度:O (1),仅使用常数额外空间。

方法二:优化遍历(O√n)

核心观察:因子成对出现(如 i 和 n/i)。只需遍历到 √n,分别处理小因子和大因子。

  1. 收集小因子:遍历 1 到 √n,收集所有小因子(≤√n)。
  2. 处理大因子:若小因子数量为 m,则大因子数量为 m(除非 n 是平方数,此时中间因子单独存在)。
  3. 分情况查找
    • 若 k ≤ m:第 k 个因子在小因子中。
    • 否则:第 k-m 个因子在大因子中(倒序查找)。
代码实现(Java)
class Solution {
    public int kthFactor(int n, int k) {
        List<Integer> smallFactors = new ArrayList<>();
        int sqrt = (int) Math.sqrt(n);
        
        // 收集小因子(≤√n)
        for (int i = 1; i <= sqrt; i++) {
            if (n % i == 0) {
                smallFactors.add(i);
            }
        }
        
        int m = smallFactors.size();
        // 情况1:k在小因子范围内
        if (k <= m) return smallFactors.get(k-1);
        
        // 情况2:处理大因子(>√n)
        int remaining = k - m;
        // 检查是否有重复的中间因子(n是平方数)
        if (smallFactors.get(m-1) * smallFactors.get(m-1) == n) {
            m--; // 中间因子已计入小因子,大因子数量减1
        }
        // 大因子数量不足
        if (remaining > m) return -1;
        
        // 大因子倒序:n/1, n/2, ..., n/(m)
        return n / smallFactors.get(m - remaining);
    }
}
复杂度分析
  • 时间复杂度:O (√n),仅遍历到平方根。
  • 空间复杂度:O (√n),存储小因子列表(最坏情况:n 是质数,存储 1 个元素)。

优化对比

方法时间复杂度空间复杂度适用场景
暴力遍历O(n)O(1)n 较小(如 ≤1e5)
优化遍历O(√n)O(√n)n 较大(如 ≥1e9)

边界情况处理

  1. k 超过总因子数:返回 -1。
  2. n 是平方数:中间因子(如 4 的因子 2)仅需计算一次。
  3. k 恰好等于小因子数量:直接返回最后一个小因子。

测试用例

nk输出因子列表
1233[1, 2, 3, 4, 6, 12]
727[1, 7]
43-1[1, 2, 4]
939[1, 3, 9]

总结

  • 暴力法:简单直观,适合小规模数据。
  • 优化法:利用因子成对特性,大幅减少遍历次数,适合大规模数据。
  • 关键优化点:分治小因子和大因子,避免重复计算。

扩展思考

  • 预处理因子:若需多次查询,可预先缓存因子列表。
  • 并行处理:分布式计算中,可拆分因子查找任务。

完整代码可在 GitHub Gist 查看。

博客结构说明

  1. 问题描述:明确输入输出及示例。
  2. 思路分析:分步解释暴力法和优化法。
  3. 代码实现:提供两种方法的完整代码。
  4. 复杂度对比:表格化展示性能差异。
  5. 边界处理:强调容易忽略的特殊情况。
  6. 测试用例:验证逻辑正确性。
  7. 总结扩展:归纳方法适用场景,提出优化方向。

此结构兼顾了初学者的理解(暴力法)和进阶需求(优化法),通过代码注释和分步解析,帮助读者逐步掌握因子查找的核心逻辑。


http://www.kler.cn/a/613024.html

相关文章:

  • 浅谈工商企业用电管理的分布式储能设计
  • window系统下安装elk
  • unity一个图片的物体,会有透明的效果
  • 【机器学习】从回声定位到优化引擎:蝙蝠算法在SVR超参数优化中的应用
  • Golang 的 GMP 调度机制常见问题及解答
  • Mininet--log.py-全局函数作用
  • Box86源码剖析(三)
  • JSP笔记
  • python多态、静态方法和类方法
  • 高速电路中的存储器应用与设计三
  • Vala 编程语言教程-继承
  • C 语言文件读写操作详解
  • Java Synchronized底层原理:Monitor机制、锁膨胀、自旋优化与偏向锁细节解密
  • 电气技术:未来自动化的心脏
  • RAG生成中的多文档动态融合及去重加权策略探讨
  • springboot 四层架构之间的关系整理笔记二
  • 【CSS3】02-选择器 + CSS特性 + 背景属性 + 显示模式
  • 硬件老化测试方案的设计误区
  • sock文件介绍--以mysql.sock为例
  • torchvision中数据集的使用