问题描述
小S在学习素数因子的分解,她希望在[1,n][1,n]的范围内,找到一些连续的自然数,这些数的乘积最多包含kk个不同的素因子。你的任务是帮助小S找到可以取的连续自然数的最大长度。
连续的自然数指的是不能重复且相邻数的差为1的一组正整数,例如 [2, 3, 4, 5]
和 [5, 6, 7]
都是连续的取数。
问题理解
我们需要在 [1, n]
的范围内找到一些连续的自然数,这些数的乘积最多包含 k
个不同的素因子。目标是找到可以取的连续自然数的最大长度。
关键点
- 素因子分解:我们需要对每个数进行素因子分解,并统计其素因子的数量。
- 滑动窗口:为了找到最大长度的连续自然数,我们可以使用滑动窗口技术来动态调整窗口的大小。
数据结构选择
- 素因子分解:可以使用一个字典来存储每个数的素因子及其数量。
- 滑动窗口:可以使用两个指针来表示窗口的左右边界。
算法步骤
-
初始化:
- 初始化一个字典来存储当前窗口内每个素因子的数量。
- 初始化两个指针
left
和right
表示窗口的左右边界,初始值均为1
。 - 初始化一个变量
max_length
来记录最大长度。
-
滑动窗口:
-
移动
right
指针,将新的数加入窗口,并更新素因子字典。 -
检查当前窗口内的素因子数量是否超过
k
:- 如果超过,移动
left
指针,缩小窗口,直到素因子数量不超过k
。
- 如果超过,移动
-
更新
max_length
。
-
-
终止条件:
- 当
right
指针超过n
时,终止循环。
- 当
代码实现
### 时间复杂度分析
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)
。
其他变量
- 其他变量(如
left
、right
、max_length
等)的空间复杂度是O(1)
。
综上所述,solution
函数的空间复杂度是 O(k)
。
总结
- 时间复杂度:
O(n * sqrt(n))
- 空间复杂度:
O(k)