在解答这道题时,我的目标是构造一个包含 n 个元素的数组,使得数组中的所有元素两两不同,并且这些元素的最大公约数为 k,同时保证数组元素之和尽可能小。这里的几个条件给出了明确的方向:
解题思路
-
最大公约数为
k的约束:- 首先,题目要求数组的所有元素的最大公约数为
k。这意味着数组中的每一个元素都必须是k的倍数。只有这样,所有元素才能拥有共同的因子k,并且保证k是这个数组的最大公约数。 - 比如,如果
k = 2,那么数组中的元素就必须是2的倍数,比如2, 4, 6, 8等。
- 首先,题目要求数组的所有元素的最大公约数为
-
保证数组元素两两不同且和尽可能小:
- 我需要尽量让数组元素之和小,所以应该从最小的
k倍数开始取元素。 - 如果我们选择的元素是
k, 2k, 3k, ..., nk,就可以确保每个元素都是k的倍数,同时彼此不同(因为每个元素是k的不同倍数)。 - 这种选择不仅满足了最大公约数为
k的要求,还保证了元素之间的最小差异,从而让总和尽可能小。
- 我需要尽量让数组元素之和小,所以应该从最小的
-
求数组元素之和:
- 选择元素为
k, 2k, 3k, ..., nk后,数组的和可以表示为:k * (1 + 2 + 3 + ... + n)。 - 根据等差数列求和公式,
1 + 2 + 3 + ... + n = n * (n + 1) / 2。所以,数组元素之和为: sum=k×n×(n+1)2\text{sum} = k \times \frac{n \times (n + 1)}{2}sum=k×2n×(n+1) - 通过这个公式,我可以直接计算出满足条件的数组元素之和的最小值,无需逐个生成和累加元素。
- 选择元素为
代码实现
在代码中,我直接使用了上述公式来计算结果:
python
Copy code
def solution(n: int, k: int) -> int:
# 计算数组元素之和的最小值
return k * n * (n + 1) // 2
if __name__ == '__main__':
# 测试用例
print(solution(n=3, k=1) == 6)
print(solution(n=2, k=2) == 6)
print(solution(n=4, k=3) == 30)
复杂度分析
- 时间复杂度:代码的时间复杂度为
O(1),因为通过一个公式即可得到结果,不需要任何循环操作。 - 空间复杂度:空间复杂度为
O(1),仅使用了常量级的辅助变量。
测试样例说明
-
样例 1:
n = 3,k = 1- 选择元素为
[1, 2, 3],和为1 + 2 + 3 = 6,符合条件。
- 选择元素为
-
样例 2:
n = 2,k = 2- 选择元素为
[2, 4],和为2 + 4 = 6,符合条件。
- 选择元素为
-
样例 3:
n = 4,k = 3- 选择元素为
[3, 6, 9, 12],和为3 + 6 + 9 + 12 = 30,符合条件。
- 选择元素为
总结
通过这种方法,我成功地利用了数学公式和数列的特性,构造出符合条件的数组并计算其最小和。这个解法不仅满足题目条件,还在性能上很高效,通过了所有测试样例验证。