数组元素之和最小化 | 豆包MarsCode AI刷题

52 阅读2分钟

问题描述

小C希望构造一个包含n个元素的数组,且满足以下条件:

  1. 数组中的所有元素两两不同。
  2. 数组所有元素的最大公约数为 k
  3. 数组元素之和尽可能小。

任务是输出该数组元素之和的最小值。

测试样例

样例1:

输入:n = 3 ,k = 1
输出:6

样例2:

输入:n = 2 ,k = 2
输出:6

样例3:

输入:n = 4 ,k = 3
输出:30

题目要求

根据题目我们需要构造一个数组,使得:

  • 数组中有 n 个不同的元素。
  • 这些元素的最大公约数为 k。
  • 数组元素之和最小。

解题思路

关键点

  1. 最大公约数为k:这意味着数组中的每一个元素都必须是 k 的倍数。
  2. 元素两两不同:为了保证所有元素不同,我们可以选择 k 的不同倍数。
  3. 元素之和最小:为了让数组元素之和最小,我们应该选择最小的 k 的倍数。

具体步骤

  1. 生成 k 的倍数:选择 k 的前 n 个倍数,即 k,2k,3k,…,nk。
  2. 计算元素之和:将这些倍数相加,得到数组元素之和。

代码解析

代码

def solution(n: int, k: int) -> int:
    # 生成 k 的前 n 个倍数
    rlist = [x * k for x in range(1, n + 1)]
    # 返回数组元素之和
    return sum(rlist)

代码详解

  1. 生成 k 的倍数

    rlist = [x * k for x in range(1, n + 1)]
    

    这行代码使用列表推导式生成了一个包含 k 的前 n 个倍数的列表。range(1, n + 1) 生成从 1 到 n 的整数,每个整数乘以 k 得到相应的倍数。

  2. 计算数组元素之和

    return sum(rlist)
    

    这行代码计算生成的数组 rlist 中所有元素的和,并返回该和,即为问题的答案。

时间复杂度为 O(1) 的解法

解法思路

为了构造一个满足条件的数组,我们选择 k 的前 n 个倍数,即 k,2k,3k,…,nk。这些元素的和可以直接通过等差数列求和公式直接计算出来,而不需要生成具体的数组,因此可以将时间复杂度降低至 O(1)

数学公式

  1. 等差数列求和公式: 等差数列的前 nn 项和公式为:
Sn=n/2×(a+l)Sn=n/2×(a+l)

其中,a 是首项,l 是第 n 项。

  1. 特殊情况: 对于 k 的前 n 个倍数 k,2k,3k,…,nk:

    • 首项 a=k
    • 第 n 项 l=nk
    • 项数 n

    代入等差数列求和公式:

Sn=n/2×(k+nk)=n/2×k(1+n)=n(n+1)/2×kSn=n/2×(k+nk)=n/2×k(1+n)=n(n+1)/2×k

代码实现

因此,以下题解可以直接求出问题答案,时间和空间复杂度均为 O(1)

def solution(n: int, k: int) -> int:
    return n * (n + 1) // 2 * k