231.小U的加法魔法

2 阅读3分钟

问题描述

小U有一个长度为 nn 的数组,她需要计算这个数组的总和 sum=a1+a2+...+ansum=a1​+a2​+...+an​。小U可以使用一次魔法,将其中一个加号变成乘号,以使得最终的总和最大。

你需要帮小U找到这个最优的方案,计算出最大的可能总和。

问题理解

小U有一个长度为 n 的数组 a,她需要计算这个数组的总和 sum = a_1 + a_2 + ... + a_n。小U可以使用一次魔法,将其中一个加号变成乘号,以使得最终的总和最大。

解题思路

  1. 计算原始总和:首先计算数组 a 的原始总和。
  2. 尝试所有可能的乘法:遍历数组中的每一对相邻元素,尝试将它们之间的加号变成乘号,计算新的总和。
  3. 比较并记录最大值:在所有可能的乘法中,记录并返回最大的总和。

数据结构的选择逻辑

  • 数组:我们使用数组来存储输入的整数序列。

算法步骤

  1. 初始化

    • 计算数组 a 的原始总和 originalSum
    • 初始化最大总和 maxSum 为 originalSum
  2. 遍历数组

    • 对于每一对相邻元素 a[i] 和 a[i+1],计算如果将它们之间的加号变成乘号后的新总和 newSum
    • 计算公式为:newSum = originalSum - a[i] - a[i+1] + a[i] * a[i+1]
  3. 更新最大总和

    • 如果 newSum 大于当前的 maxSum,则更新 maxSum
  4. 返回结果

    • 返回 maxSum 作为最终结果。

总结

通过上述步骤,我们可以有效地找到通过将其中一个加号变成乘号后得到的最大可能总和。这个方法的时间复杂度为 O(n),其中 n 是数组的长度,因为我们只需要遍历数组一次。

solution完整代码

    public static int solution(int n, int[] a) {
        // 计算原始总和
        int originalSum = 0;
        for (int num : a) {
            originalSum += num;
        }

        // 初始化最大总和为原始总和
        int maxSum = originalSum;

        // 尝试将每个加号变成乘号
        for (int i = 0; i < n - 1; i++) {
            // 计算新的总和,如果将 a[i] 和 a[i+1] 之间的加号变成乘号
            int newSum = originalSum - a[i] - a[i + 1] + a[i] * a[i + 1];
            // 更新最大总和
            if (newSum > maxSum) {
                maxSum = newSum;
            }
        }

        return maxSum;
    }

代码优化

  1. 减少重复计算

    • 在当前代码中,每次计算 newSum 时都会重新计算 originalSum 减去 a[i] 和 a[i+1] 的部分。我们可以通过在循环外计算 originalSum 的初始值,然后在循环内直接使用这个值来减少重复计算。
  2. 边界条件检查

    • 在当前代码中,我们假设 n 至少为2,因为我们需要至少一对相邻元素来进行乘法操作。如果 n 小于2,我们可以直接返回原始总和。

结果分析

当前代码的输出结果是正确的,符合预期。代码通过遍历数组中的每一对相邻元素,尝试将它们之间的加号变成乘号,并记录最大的总和。