豆包刷题:数组元素之和最小化

44 阅读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

问题分析

  1. 最大公约数为 k

    • 数组中每个元素的最大公约数为 k,也就是说,数组中的每个元素都应该是 k 的倍数。可以将所有元素表示为 k * x 的形式,其中 x 是正整数。
  2. 元素两两不同

    • 数组中的所有元素必须是不同的,这意味着 x 的取值必须是不同的整数。
  3. 元素之和尽可能小

    • 我们需要选择不同的 x,使得数组元素之和最小。

解题思路

  1. 选择最小的不同倍数

    • 为了让元素之和最小,我们应该尽可能选择最小的 x 值。最小的不同正整数是 1, 2, 3, 4, ...
  2. 元素构造

    • 由于我们要求最大公约数为 k,所以我们可以构造数组元素为 k * 1, k * 2, k * 3, ..., k * n,即数组元素是 k 的倍数。
  3. 数组元素之和

    • 数组的元素是 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. 样例1

    • 输入:n = 3k = 1
    • 计算:最小的数组是 [1, 2, 3],元素和为 1 + 2 + 3 = 6,因此输出 6
  2. 样例2

    • 输入:n = 2k = 2
    • 计算:最小的数组是 [2, 4],元素和为 2 + 4 = 6,因此输出 6
  3. 样例3

    • 输入:n = 4k = 3
    • 计算:最小的数组是 [3, 6, 9, 12],元素和为 3 + 6 + 9 + 12 = 30,因此输出 30

时间复杂度

  • 计算和的时间复杂度是 O(1),因为我们只是做了一个简单的数学计算。

空间复杂度

  • 空间复杂度是 O(1),因为只使用了常数级别的空间。