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

89 阅读4分钟

题目描述

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

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

输入

n=3,k=1n = 3, k = 1

输出

6

思路分析

问题分析

  1. 构造目标 我们需要构造一个大小为 ( n ) 的数组,满足以下条件:

    • 数组中的元素两两不同;
    • 所有元素的最大公约数 (GCD) 为 ( k );
    • 数组元素之和尽可能小。
  2. 条件推导

    • GCD的影响 如果数组的最大公约数是 ( k ),则数组的所有元素都必须是 ( k ) 的倍数。这是由最大公约数的定义决定的。
    • 两两不同的要求 为了满足元素两两不同,最简单的选择是选取 ( k, 2k, 3k, \ldots, nk )。
    • 最小化数组和 为了使数组之和最小,我们可以从最小的 ( k ) 倍数开始按顺序选取,直到选够 ( n ) 个。

算法设计

任务目标分解

  1. 确保所有条件被满足

    • 条件 1:所有元素两两不同。

      • 要求数组中的元素不重复,且彼此之间没有相同的值。
      • 我们选择按倍数递增的方法,选取 k,2k,3k,,nkk, 2k, 3k, \ldots, nk,这样可以轻松保证两两不同。
    • 条件 2:所有元素的最大公约数是 k。

      • 如果所有元素都是 k 的倍数,且最小值是 k,那么数组的 GCD 为 k。选择连续的 k 倍数满足此条件。
    • 条件 3:数组的总和尽可能小。

      • 最小化数组和意味着从最小值开始构造数组,依次选择 k,2k,3k,,nkk, 2k, 3k, \ldots, nk
  2. 简化问题

    • 确定了数组的构造规则后,问题变为求出数组元素的和: S=k+2k+3k++nkS = k + 2k + 3k + \ldots + nk
    • 进一步简化为: S=k×(1+2+3++n)S = k \times (1 + 2 + 3 + \ldots + n)
    • 利用等差数列求和公式计算: 1+2++n=n×(n+1)21 + 2 + \ldots + n = \frac{n \times (n + 1)}{2} 所以: S=k×n×(n+1)2S = k \times \frac{n \times (n + 1)}{2}

具体算法设计

  1. 输入分析

    • 输入两个参数 n 和 k,分别表示数组长度和最大公约数。
    • 输入限制:n 和 k 均为正整数。
  2. 公式构造

    • 数组元素由 k,2k,3k,,nkk, 2k, 3k, \ldots, nk 构成。
    • 数组的总和公式为: S=k×n×(n+1)2S = k \times \frac{n \times (n + 1)}{2}
  3. 实现步骤

    • 第一步:计算等差数列的和: Sum=n×(n+1)2Sum = \frac{n \times (n + 1)}{2}
    • 第二步:乘以 k 得到最终结果: S=k×SumS = k \times Sum
    • 第三步:返回结果。
  4. 优化操作

    • 使用整数运算避免浮点误差;
    • 避免循环构造数组,直接使用公式计算,提升效率。

难点分析

  1. 理解 GCD 的约束 确保数组的最大公约数为 ( k ) 是核心难点,尤其是如何从数学角度解释和实现这一约束。具体来说:

    • 若数组中存在一个元素不是 ( k ) 的倍数,则 ( GCD \neq k );
    • 若数组中有两个数的 GCD 小于 ( k ),则整个数组的 GCD 也会小于 ( k )。
  2. 保证两两不同且最小和

    • 元素两两不同的要求限制了可以选择的数的范围;
    • 要让和最小,必须从最小的数开始,这对设计优化方案至关重要。
  3. 公式化思路 将问题抽象为公式并快速求解,既需要数学推导能力,也需要确保公式的正确性。


用到的算法

  1. 数学推导 本题主要依赖于数列求和公式和 GCD 的性质,没有涉及复杂的算法。利用 ( k ) 的倍数构造数组,并通过公式化的方法高效求解。
  2. 贪心思想 贪心策略的体现为从最小的数开始选取,以保证最终结果的总和最小。

代码分析

代码逻辑

  1. 输入与参数解析

    • ( n ):数组长度;
    • ( k ):最大公约数。
  2. 核心计算

    • 根据推导公式计算最小和: Sum=k×n×(n+1)2\text{Sum} = k \times \frac{n \times (n + 1)}{2}
  3. 返回结果

    • 代码直接返回计算结果,时间复杂度为 ( O(1) )。
 int solution(int n, int k) {
     // write code here
     return k * (1 + n) * n / 2;
 }
 ​

代码简洁性

  • 代码通过公式一步求解,避免了复杂的循环或数组操作,效率非常高。
  • 数学推导和代码实现直接对应,便于理解和扩展。

复杂度分析

  1. 时间复杂度

    • 构造数组的复杂度:公式计算直接完成,无需构造实际数组,为 ( O(1) )。
    • 总复杂度:( O(1) )。
  2. 空间复杂度

    • 代码不需要额外存储数组,只存储中间变量,空间复杂度为 ( O(1) )。

总结

  1. 思路清晰 本题通过数学推导直接解决问题,避免了复杂的数据结构操作。核心在于理解 GCD 对数组的约束,并将其转化为一个等差数列求和问题。

  2. 公式高效 使用公式直接计算结果,保证了代码的简洁性和高效性,适合大规模输入场景。

  3. 代码特点

    • 简单、直观,体现了数学推导的优势;
    • 时间复杂度和空间复杂度均为 ( O(1) ),非常高效。