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

54 阅读2分钟

题目重现

image.png

题目分析

这个问题是一个数学优化问题,我们需要找到一组满足特定条件的最小和数组。具体来说,我们需要找到一个包含n个元素的数组,这些元素满足以下条件:

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

为了解决这个问题,我们可以采取以下步骤进行分析:

1. 理解问题

  • 两两不同:数组中的任意两个元素都不能相同。
  • 最大公约数为k:数组中任意两个元素的GCD都是k,这意味着所有元素都可以被k整除。
  • 元素之和最小:我们需要找到一个和最小的数组。

2. 特殊情况处理

  • 当k=1时,任何整数都是1的倍数,因此我们可以简单地选择最小的n个正整数(1, 2, 3, ..., n)作为数组元素,它们的和为( \frac{n(n+1)}{2} )。

3. 一般情况处理

  • 当k不等于1时,我们需要找到n个不同的k的倍数,使得它们的和最小。
  • 由于所有元素必须是k的倍数,我们可以从k开始,每次增加k,直到我们找到n个不同的数。这是因为k的最小倍数是k本身,下一个最小的倍数是2k,依此类推。

4. 构造数组

  • 我们可以构造一个数组,其中第一个元素是k,第二个元素是2k,第三个元素是3k,以此类推,直到第n个元素是nk。

5. 计算和

  • 这个数组的和就是等差数列的和,首项为k,公差为k,项数为n,所以和为( k + 2k + 3k + ... + nk )。
  • 这个和可以用等差数列求和公式计算:( S = \frac{n}{2} \times (首项 + 末项) ),即( S = \frac{n}{2} \times (k + nk) )。

6. 实现算法

  • 根据上述分析,我们可以编写一个函数,当k=1时直接计算等差数列的和,否则从k开始,每次增加k,直到找到n个不同的数,然后计算这些数的和。

代码

def solution(n: int, k: int) -> int:
    # 如果k为1,那么最小的不同元素就是从1开始的连续整数
    if k == 1:
        return n * (n + 1) // 2
    
    # 初始化数组和为0
    total_sum = 0
    # 初始化当前元素为k
    current = k
    # 循环直到数组中有n个元素
    for _ in range(n):
        total_sum += current
        # 为了找到下一个不同的元素,我们加上k,因为所有元素的最大公约数为k
        current += k
    
    return total_sum

if __name__ == '__main__':
    print(solution(n = 3, k = 1) == 6)
    print(solution(n = 2, k = 2) == 6)
    print(solution(n = 4, k = 3) == 30)