算法题详解:数组元素之和最小化(中等题14)| 豆包MarsCode AI刷题

55 阅读4分钟

问题描述

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

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

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

做题思路

1. 问题分析

  • 条件1:数组中的所有元素必须两两不同。
  • 条件2:数组所有元素的最大公约数为 ( k )。
  • 条件3:数组元素之和尽可能小。

为了满足这些条件,我们可以考虑以下策略:

  • 选择最小的 ( n ) 个互不相同的数:为了使数组元素之和尽可能小,我们应该选择最小的 ( n ) 个互不相同的数。
  • 确保最大公约数为 ( k ):为了使这些数的最大公约数为 ( k ),我们可以选择 ( k ) 的倍数。具体来说,选择 ( k, 2k, 3k, \ldots, nk )。

2. 关键点

  • 选择 ( k ) 的倍数:选择 ( k, 2k, 3k, \ldots, nk ) 这 ( n ) 个数,这些数的最大公约数显然是 ( k )。
  • 求和:这些数的和可以通过等差数列求和公式来计算。

3. 解决方案

  • 等差数列求和公式:等差数列的前 ( n ) 项和公式为 ( S_n = \frac{n}{2} \times (a_1 + a_n) ),其中 ( a_1 ) 是首项,( a_n ) 是第 ( n ) 项。
  • 应用到本题:首项 ( a_1 = k ),第 ( n ) 项 ( a_n = nk ),所以前 ( n ) 项和为 ( S_n = \frac{n}{2} \times (k + nk) )。

做题方式

  1. 计算前 ( n ) 个 ( k ) 的倍数的和

    • 使用等差数列求和公式 ( S_n = \frac{n}{2} \times (k + nk) )。
  2. 返回结果

    • 计算出的和即为所求的最小值。

详细代码讲解

public class Main {
    public static int solution(int n, int k) {
        // 使用等差数列求和公式计算前 n 个 k 的倍数的和
        int sum = (n * (k + n * k)) / 2;
        return sum;
    }

    public static void main(String[] args) {
        // 测试用例
        System.out.println(solution(3, 1) == 6);  // 输出 6
        System.out.println(solution(2, 2) == 6);  // 输出 6
        System.out.println(solution(4, 3) == 30); // 输出 30
    }
}

代码解析

  1. 方法定义

    • public static int solution(int n, int k):定义一个静态方法 solution,接收两个整数参数 nk,返回一个整数。
  2. 计算前 ( n ) 个 ( k ) 的倍数的和

    • 使用等差数列求和公式 ( S_n = \frac{n}{2} \times (k + nk) ) 计算前 ( n ) 个 ( k ) 的倍数的和。
    • int sum = (n * (k + n * k)) / 2;:计算前 ( n ) 个 ( k ) 的倍数的和。
  3. 返回结果

    • return sum;:返回计算出的和。
  4. 测试用例

    • System.out.println(solution(3, 1) == 6);:测试用例1,输出 true 表示结果正确。
    • System.out.println(solution(2, 2) == 6);:测试用例2,输出 true 表示结果正确。
    • System.out.println(solution(4, 3) == 30);:测试用例3,输出 true 表示结果正确。

总结

通过使用等差数列求和公式,我们可以在 ( O(1) ) 时间复杂度内计算出满足条件的数组元素之和的最小值。这种方法不仅高效,而且简洁,非常适合解决这类问题。希望这篇笔记对你有所帮助,如果你有任何疑问或需要进一步的解释,请随时联系我!

扩展思考

  1. 多于一个最大公约数的情况

    • 如果数组中有多于一个最大公约数,如何找到所有可能的数组?
    • 一种方法是枚举所有可能的最大公约数,然后分别计算每个最大公约数对应的数组元素之和,选择最小的和。
  2. 扩展到多个数组

    • 如果有多个数组,每个数组中都有一个特定的最大公约数,如何高效地找到所有数组中的最小和?
    • 可以考虑将所有数组的最大公约数和元素个数作为输入,然后分别计算每个数组的最小和,最后取所有最小和的和。
  3. 实际应用

    • 这种方法在数学和算法竞赛中非常常见,尤其是在需要高效处理数论问题的情况下。
    • 例如,在优化资源分配问题中,可以利用类似的思想来快速找到最优解。

希望这些扩展思考能帮助你更深入地理解这个问题,并激发你在算法领域的探索兴趣。如果你有更多的问题或想法,欢迎随时交流!