178.小C的连续自然数乘积问题 | 豆包MarsCode AI 刷题

51 阅读3分钟

问题描述

小S在学习素数因子的分解,她希望在[1,n][1,n]的范围内,找到一些连续的自然数,这些数的乘积最多包含kk个不同的素因子。你的任务是帮助小S找到可以取的连续自然数的最大长度。

连续的自然数指的是不能重复且相邻数的差为1的一组正整数,例如 [2, 3, 4, 5] 和 [5, 6, 7] 都是连续的取数。

问题理解

我们需要在 [1, n] 的范围内找到一些连续的自然数,这些数的乘积最多包含 k 个不同的素因子。目标是找到可以取的连续自然数的最大长度。

关键点

  1. 素因子分解:我们需要对每个数进行素因子分解,并统计其素因子的数量。
  2. 滑动窗口:为了找到最大长度的连续自然数,我们可以使用滑动窗口技术来动态调整窗口的大小。

数据结构选择

  • 素因子分解:可以使用一个字典来存储每个数的素因子及其数量。
  • 滑动窗口:可以使用两个指针来表示窗口的左右边界。

算法步骤

  1. 初始化

    • 初始化一个字典来存储当前窗口内每个素因子的数量。
    • 初始化两个指针 left 和 right 表示窗口的左右边界,初始值均为 1
    • 初始化一个变量 max_length 来记录最大长度。
  2. 滑动窗口

    • 移动 right 指针,将新的数加入窗口,并更新素因子字典。

    • 检查当前窗口内的素因子数量是否超过 k

      • 如果超过,移动 left 指针,缩小窗口,直到素因子数量不超过 k
    • 更新 max_length

  3. 终止条件

    • 当 right 指针超过 n 时,终止循环。

代码实现

image.png ### 时间复杂度分析

update_prime_factors 函数

  • 这个函数用于分解 num 的素因子,并更新 prime_factors 字典。
  • 对于一个数 num,我们需要检查从 2 到 sqrt(num) 的所有数,看看它们是否是 num 的因子。
  • 因此,update_prime_factors 的时间复杂度是 O(sqrt(num))

remove_prime_factors 函数

  • 这个函数用于移除 num 的素因子,并更新 prime_factors 字典。
  • 类似于 update_prime_factors,它的时间复杂度也是 O(sqrt(num))

count_distinct_primes 函数

  • 这个函数用于统计 prime_factors 字典中不同素因子的数量。
  • 它的时间复杂度是 O(1),因为只需要返回字典的长度。

solution 函数

  • 在 solution 函数中,我们使用滑动窗口技术来找到最大长度的连续自然数。
  • right 指针从 1 遍历到 n,因此外层循环的时间复杂度是 O(n)
  • 对于每个 right,我们调用 update_prime_factors,其时间复杂度是 O(sqrt(right))
  • 在每次移动 left 指针时,我们调用 remove_prime_factors,其时间复杂度是 O(sqrt(left))
  • 因此,内层循环的总时间复杂度是 O(n * sqrt(n))

综上所述,solution 函数的时间复杂度是 O(n * sqrt(n))

空间复杂度分析

prime_factors 字典

  • prime_factors 字典用于存储当前窗口内每个素因子的数量。
  • 在最坏情况下,prime_factors 字典的大小不会超过 k,因为题目要求素因子数量不超过 k
  • 因此,prime_factors 字典的空间复杂度是 O(k)

其他变量

  • 其他变量(如 leftrightmax_length 等)的空间复杂度是 O(1)

综上所述,solution 函数的空间复杂度是 O(k)

总结

  • 时间复杂度O(n * sqrt(n))
  • 空间复杂度O(k)