问题描述
小C希望构造一个包含n个元素的数组,且满足以下条件:
- 数组中的所有元素两两不同。
- 数组所有元素的最大公约数为
k。 - 数组元素之和尽可能小。
任务是输出该数组元素之和的最小值。
测试样例
样例1:
输入:
n = 3 ,k = 1
输出:6
样例2:
输入:
n = 2 ,k = 2
输出:6
样例3:
输入:
n = 4 ,k = 3
输出:30
问题分析
-
最大公约数为 k:
- 数组中每个元素的最大公约数为
k,也就是说,数组中的每个元素都应该是k的倍数。可以将所有元素表示为k * x的形式,其中x是正整数。
- 数组中每个元素的最大公约数为
-
元素两两不同:
- 数组中的所有元素必须是不同的,这意味着
x的取值必须是不同的整数。
- 数组中的所有元素必须是不同的,这意味着
-
元素之和尽可能小:
- 我们需要选择不同的
x,使得数组元素之和最小。
- 我们需要选择不同的
解题思路
-
选择最小的不同倍数:
- 为了让元素之和最小,我们应该尽可能选择最小的
x值。最小的不同正整数是1, 2, 3, 4, ...。
- 为了让元素之和最小,我们应该尽可能选择最小的
-
元素构造:
- 由于我们要求最大公约数为
k,所以我们可以构造数组元素为k * 1, k * 2, k * 3, ..., k * n,即数组元素是k的倍数。
- 由于我们要求最大公约数为
-
数组元素之和:
-
数组的元素是
k, 2k, 3k, ..., nk,其和为:k*n(n + 1)/2 -
这是因为
1 + 2 + 3 + ... + n是一个等差数列的求和公式,和为n(n + 1)/2。
-
def solution(n: int, k: int) -> int:
# 从 k 开始,每次增加 k,构造 n 个不同的元素
elements = [k * (i + 1) for i in range(n)]
# 返回这些元素的和
return sum(elements)
if __name__ == '__main__':
print(solution(n = 3, k = 1) == 6)
print(solution(n = 2, k = 2) == 6)
print(solution(n = 4, k = 3) == 30)
解释
n * (n + 1) // 2是等差数列的和公式,用来计算从1到n的所有整数之和。- 将该和乘以
k就是数组元素之和的最小值。
测试样例解析
-
样例1:
- 输入:
n = 3,k = 1 - 计算:最小的数组是
[1, 2, 3],元素和为1 + 2 + 3 = 6,因此输出6。
- 输入:
-
样例2:
- 输入:
n = 2,k = 2 - 计算:最小的数组是
[2, 4],元素和为2 + 4 = 6,因此输出6。
- 输入:
-
样例3:
- 输入:
n = 4,k = 3 - 计算:最小的数组是
[3, 6, 9, 12],元素和为3 + 6 + 9 + 12 = 30,因此输出30。
- 输入:
时间复杂度
- 计算和的时间复杂度是
O(1),因为我们只是做了一个简单的数学计算。
空间复杂度
- 空间复杂度是
O(1),因为只使用了常数级别的空间。