豆包MarsCode算法题:小U的加法魔法

问题描述

在这里插入图片描述


思路分析

1. 问题拆解

  • 初始情况下,数组的总和为所有元素的简单相加:
    在这里插入图片描述

  • 我们可以选择 任意相邻的两个元素 a[i]a[i+1] ,将它们的加法替换为乘法:
    在这里插入图片描述

    这里的 增量 是:
    在这里插入图片描述

  • 因此问题就转化为:在所有可能的 increment 中,找到最大的一个,并将其加入到初始总和中。

2. 计算增量的优化

我们需要观察增量:
在这里插入图片描述

  • 进一步整理为:
    在这里插入图片描述

  • 增量的值取决于两个数的大小:

    • 当两个数都比较大时,增量也会更大。
    • 因此,我们只需要遍历数组中的每一对相邻元素,分别计算增量,记录最大值。

3. 具体步骤

  1. 初始化

    • 计算数组初始总和 originalSum
    • 初始化一个变量 maxSum 用于存储最大可能的总和,初始值为 originalSum
  2. 遍历计算增量

    • 遍历数组的每一对相邻元素 ( a[i] ) 和 ( a[i+1] )。
    • 计算替换操作带来的增量 ( \text{increment} )。
    • 更新当前总和:currentSum = originalSum + increment
    • maxSum 记录所有替换操作中最大的总和。
  3. 返回结果

    • 最终返回 maxSum,即经过优化后的最大可能总和。

4. 时间复杂度分析

  • 遍历数组
    • 我们只需要遍历一次数组中的每一对相邻元素,时间复杂度为 O(n)
  • 空间复杂度
    • 除了少量的辅助变量,算法不需要额外空间,空间复杂度为 O(1)

参考代码(Java)

public class Main {
    public static int solution(int n, int[] a) {
        // 初始总和
        int originalSum = 0;
        for (int value : a) {
            originalSum += value;
        }
        
        int maxSum = originalSum;
        
        // 遍历每一对相邻元素,将加号替换为乘号
        for (int i = 0; i < n - 1; i++) {
            int currentSum = originalSum;
            
            // 替换加号为乘号的增量
            int increment = a[i] * a[i + 1] - (a[i] + a[i + 1]);
            
            // 更新总和
            currentSum += increment;
            
            // 更新最大可能的总和
            maxSum = Math.max(maxSum, currentSum);
        }
        
        return maxSum;
    }

    public static void main(String[] args) {
        System.out.println(solution(6, new int[]{1, 1, 4, 5, 1, 4}) == 27);
        System.out.println(solution(3, new int[]{2, 3, 5}) == 17);
    }
}

代码分析

  1. 计算初始总和

    int originalSum = 0;
    for (int value : a) {
        originalSum += value;
    }
    
    • 通过遍历数组,将所有元素相加得到初始总和 originalSum
    • 时间复杂度为 O(n)
  2. 遍历相邻元素对

    for (int i = 0; i < n - 1; i++) {
    
    • 遍历数组中每一对相邻元素(下标 ii+1 ),目的是尝试将对应的加号替换为乘号。
  3. 计算替换后的增量

    int increment = a[i] * a[i + 1] - (a[i] + a[i + 1]);
    
    • a[i] * a[i+1] 是替换成乘号后这对元素的结果。
    • a[i] + a[i+1] 是原本加法下的结果。
    • increment 表示将加号替换为乘号所带来的增量。
  4. 更新当前总和和最大总和

    currentSum += increment;
    maxSum = Math.max(maxSum, currentSum);
    
    • 将增量加入原始总和,得到当前替换方案下的总和。
    • 使用 Math.max 找到所有替换方案中的最大值,并更新 maxSum
  5. 返回结果

    return maxSum;
    
    • 最终返回通过最优替换后的最大总和。

参考代码(Python)

def solution(n: int, a: list) -> int:
    # 计算初始总和
    original_sum = sum(a)
    max_sum = original_sum

    # 遍历每对相邻元素,计算替换后的增量
    for i in range(n - 1):
        # 替换加号为乘号的增量
        increment = a[i] * a[i + 1] - (a[i] + a[i + 1])
        # 更新最大可能的总和
        max_sum = max(max_sum, original_sum + increment)

    return max_sum

if __name__ == '__main__':
    # 测试用例
    print(solution(6, [1, 1, 4, 5, 1, 4]) == 27)  # 输出 True
    print(solution(3, [2, 3, 5]) == 17)          # 输出 True

代码分析

  1. 计算初始总和

    original_sum = sum(a)
    
    • 通过 sum 函数计算所有数组元素的总和。
    • 这是在没有任何替换操作时的初始总和。
  2. 初始化最大总和

    max_sum = original_sum
    
    • 将初始总和赋值为 max_sum,作为当前已知的最大总和。
  3. 遍历数组中每对相邻元素

    for i in range(n - 1):
    
    • 遍历 n-1 对相邻元素,尝试将每对的加号替换为乘号。
  4. 计算替换操作的增量

    increment = a[i] * a[i + 1] - (a[i] + a[i + 1])
    
    • 替换后的增量公式:
      在这里插入图片描述

    • 逻辑解释

      • a[i] * a[i+1] 是替换为乘号后的结果。
      • a[i] + a[i+1] 是原本加法下的结果。
      • 增量 increment 表示替换操作对总和的影响。
  5. 更新最大总和

    max_sum = max(max_sum, original_sum + increment)
    
    • 对每次替换后的总和 original_sum + increment 与当前最大总和 max_sum 进行比较,取最大值。
    • 遍历结束后,max_sum 即为所有替换操作中的最优解。
  6. 返回结果

    return max_sum
    
    • 返回替换操作后可能获得的最大总和。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

凭君语未可

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值