题目描述
小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的倍数组成数组。这意味着数组的前n个元素应为:元素=k,2k,3k,…,nk\text{元素} = k, 2k, 3k, \ldots, nk
解题步骤
-
生成
k的倍数:
按从小到大的顺序生成k的倍数,依次取k, 2k, 3k, ..., nk。 -
计算元素之和:
通过数学公式求和,前n个k的倍数之和为:S=k×(1+2+⋯+n)=k×n×(n+1)2S = k \times (1 + 2 + \cdots + n) = k \times \frac{n \times (n + 1)}{2}
代码实现
以下是基于上述思路的 Python 实现:
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
代码解释
-
公式计算:
k * n * (n + 1) // 2:计算前n个k的倍数之和。
-
简化实现:
- 不需要显式构造数组,通过数学公式直接得到最优解,减少了代码复杂性和运行时间。
测试分析
通过以下测试样例验证代码的正确性:
| 输入 | 输出 | 解释 |
|---|---|---|
n=3, k=1 | 6 | 最小数组为 [1, 2, 3] |
n=2, k=2 | 6 | 最小数组为 [2, 4] |
n=4, k=3 | 30 | 最小数组为 [3, 6, 9, 12] |
边界情况
-
n=1, k=1:- 输出
1,最小数组为[1]。
- 输出
-
n=1, k=100:- 输出
100,最小数组为[100]。
- 输出
总结
- 本题通过观察和公式计算简化了实现,避免了复杂的数组操作。
- 时间复杂度为 O(1),非常的高效。