要解决这个问题,我们需要构造一个包含 n 个元素的数组,满足以下条件:
- 数组中的所有元素两两不同。
- 数组所有元素的最大公约数为
k。 - 数组元素之和尽可能小。
解题思路
-
理解题目要求:
- 数组中的元素必须是
k的倍数,因为最大公约数为k。 - 数组中的元素必须两两不同,这意味着我们需要选择不同的
k的倍数。 - 数组元素之和要尽可能小,这意味着我们应该选择最小的
k的倍数。
- 数组中的元素必须是
-
选择合适的元素:
- 为了满足所有元素两两不同且最大公约数为
k,我们可以从k开始,每次增加k,直到选择n个不同的元素。 - 例如,如果
k = 1,我们可以选择1, 2, 3, ...直到n个元素。 - 如果
k = 2,我们可以选择2, 4, 6, ...直到n个元素。
- 为了满足所有元素两两不同且最大公约数为
-
计算最小和:
- 选择这些元素后,直接计算它们的和即可。
-
算法步骤
-
初始化一个变量
sum用于存储数组元素之和。 -
初始化一个变量
current为k,表示当前选择的元素。 -
循环
n次,每次将current加到sum中,并将current增加k,以确保下一个元素是k的倍数且不同。 -
返回
sum。
通过这种方式,我们可以确保数组中的元素两两不同且最大公约数为 k,同时数组元素之和尽可能小。
代码分析
- solution 函数 def solution(n: int, k: int) -> int: 1 功能:该函数的作用是返回一个包含 n 个元素的数组,其满足题目的条件:数组中的元素两两不同,所有元素的最大公约数为 k,并且这些元素之和尽可能小。 参数: n: 数组中元素的个数。 k: 数组中每个元素的最大公约数。
- 计算 1 + 2 + 3 + ... + n 的和 sum_of_first_n = n * (n + 1) // 2 1 解释:为了尽可能使数组元素之和最小,我们选择最小的 n 个互质数,这些数是 1, 2, 3, ..., n。
数学公式:1 + 2 + 3 + ... + n 的和是一个经典的数学公式:
该公式计算的是从 1 到 n 的所有整数的和。这个公式的时间复杂度是 O(1),只需要常数时间即可计算出结果。
具体实现:使用整数除法 // 来确保计算结果为整数(在 Python 中,/ 默认会返回浮动类型,而我们这里需要整数结果)。
- 乘以 k 得到最终的数组元素之和 return k * sum_of_first_n 1 解释:计算完 1 + 2 + 3 + ... + n 的和后,乘以 k 得到数组中所有元素的和。 例如,数组中的元素是 k, 2k, 3k, ..., nk,这些元素的和就是 k * (1 + 2 + 3 + ... + n),即 k 乘以 sum_of_first_n。 由于我们已经在前一步计算了 sum_of_first_n,这一步是将它乘以 k 得到最终的结果。
- 主程序(if name == 'main':) if name == 'main': print(solution(n = 3, k = 1) == 6) # 1+2+3 = 6 print(solution(n = 2, k = 2) == 6) # 2+4 = 6 print(solution(n = 4, k = 3) == 30) # 3+6+9+12 = 30 1 2 3 4 这里的 if name == 'main': 用来检查该文件是否作为主程序执行。如果是,代码就会运行里面的测试代码;如果这个文件被作为模块导入,里面的测试代码就不会执行。 测试: solution(n = 3, k = 1) 返回的是 6,因为选取的是 1, 2, 3,它们的和是 6。 solution(n = 2, k = 2) 返回的是 6,选取的是 2, 4,它们的和是 6。 solution(n = 4, k = 3) 返回的是 30,选取的是 3, 6, 9, 12,它们的和是 30。 代码的时间复杂度分析: 计算和 1 + 2 + 3 + ... + n:这部分使用了数学公式,时间复杂度是 O(1)。 乘以 k:这只是一个常数乘法操作,时间复杂度也是 O(1)。 总时间复杂度:由于这两个操作的时间复杂度都是 O(1),所以整体时间复杂度是 O(1)。 代码的空间复杂度分析: 该函数只使用了常数空间(除了输入和输出),所以空间复杂度也是 O(1)。