问题描述
小C希望构造一个包含n个元素的数组,且满足以下条件:
- 数组中的所有元素两两不同。
- 数组所有元素的最大公约数为
k。 - 数组元素之和尽可能小。
任务是输出该数组元素之和的最小值。
测试样例
样例1:
输入:
n = 3 ,k = 1
输出:6
样例2:
输入:
n = 2 ,k = 2
输出:6
样例3:
输入:
n = 4 ,k = 3
输出:30
题目要求
根据题目我们需要构造一个数组,使得:
- 数组中有 n 个不同的元素。
- 这些元素的最大公约数为 k。
- 数组元素之和最小。
解题思路
关键点
- 最大公约数为k:这意味着数组中的每一个元素都必须是 k 的倍数。
- 元素两两不同:为了保证所有元素不同,我们可以选择 k 的不同倍数。
- 元素之和最小:为了让数组元素之和最小,我们应该选择最小的 k 的倍数。
具体步骤
- 生成 k 的倍数:选择 k 的前 n 个倍数,即 k,2k,3k,…,nk。
- 计算元素之和:将这些倍数相加,得到数组元素之和。
代码解析
代码
def solution(n: int, k: int) -> int:
# 生成 k 的前 n 个倍数
rlist = [x * k for x in range(1, n + 1)]
# 返回数组元素之和
return sum(rlist)
代码详解
-
生成 k 的倍数:
rlist = [x * k for x in range(1, n + 1)]这行代码使用列表推导式生成了一个包含 k 的前 n 个倍数的列表。
range(1, n + 1)生成从 1 到 n 的整数,每个整数乘以 k 得到相应的倍数。 -
计算数组元素之和:
return sum(rlist)这行代码计算生成的数组
rlist中所有元素的和,并返回该和,即为问题的答案。
时间复杂度为 O(1) 的解法
解法思路
为了构造一个满足条件的数组,我们选择 k 的前 n 个倍数,即 k,2k,3k,…,nk。这些元素的和可以直接通过等差数列求和公式直接计算出来,而不需要生成具体的数组,因此可以将时间复杂度降低至 O(1)。
数学公式
- 等差数列求和公式: 等差数列的前 nn 项和公式为:
其中,a 是首项,l 是第 n 项。
-
特殊情况: 对于 k 的前 n 个倍数 k,2k,3k,…,nk:
- 首项 a=k
- 第 n 项 l=nk
- 项数 n
代入等差数列求和公式:
代码实现
因此,以下题解可以直接求出问题答案,时间和空间复杂度均为 O(1)。
def solution(n: int, k: int) -> int:
return n * (n + 1) // 2 * k