最大化特定表达式的计算| 豆包MarsCode AI 刷题

40 阅读2分钟

题目分析

小S拿到了一个长度为几的环形数组,并定义了两个下标之和j的贡献值公式为:f(i,j)=(a i + a_j)x dist(i,j)其中 dist(i,j)是下标之和?在数组中的最短距离。小S希望找到一对下标,使得它们的贡献值尽可能大。环形数组的特点是最左和最右的元素也是相邻的。你需要帮助她找到最大贡献值。 例如,给定数组[1,2,3],由于是环形数组,任意两个下标的距离都是1,因此 f(2,3)=(2+3)x1=5.

测试样例

样例1:

输入:n=3,a=[1,2,3]

输出:5

样例2:

输入:n=4,a=[4,1,2,3]

输出:12

样例3:

输入:n=5,a=[1,5,3,7,2]

输出:24

思路

  1. 双重循环遍历:由于我们需要比较所有可能的 (i) 和 (j) 组合,最直接的方式是使用双重循环。外层循环遍历 (i),内层循环遍历 (j)(从 (i + 1) 开始),以确保 (i < j)。

  2. 计算表达式:在每次选择 (i) 和 (j) 时,计算 ((a[i] + a[j])) 和 (\min(j - i, n - j + i))。将这两者的乘积与当前的最大值进行比较,并更新最大值。

  3. 返回结果:遍历完成后,返回得到的最大值。

代码

下面是实现上述思路的代码:

#include <iostream>
#include <vector>
#include <string>

using namespace std;

int solution(int n, std::vector<int> a) 
{
    int res = 0;  // 初始化结果为0
    for(int i = 0; i < n; i++)  // 遍历所有可能的i
    {
        for(int j = i + 1; j < n; j++)  // 遍历所有可能的j
        {
            // 计算 (a[i] + a[j]) * min(j - i, n - j + i)
            res = max(res, (a[i] + a[j]) * min(j - i, n - j + i));
        }
    }

    return res;  // 返回最大值
}

int main() 
{
    std::cout << (solution(3, {1, 2, 3}) == 5) << std::endl;
    std::cout << (solution(4, {4, 1, 2, 3}) == 12) << std::endl;
    std::cout << (solution(5, {1, 5, 3, 7, 2}) == 24) << std::endl;
    return 0;
}

代码分析

  1. 初始化:首先我们定义一个变量 res 用于存储当前的最大值,初始值为0。

  2. 双重循环:外层循环遍历所有可能的 (i),内层循环从 (i + 1) 开始遍历 (j)。这样可以确保 (i < j)。

  3. 计算表达式:在内层循环中,我们计算表达式的值,并使用 max 函数更新 res

  4. 返回结果:所有组合计算完成后,返回 res 作为最终结果。

复杂度分析

  • 时间复杂度:由于使用了双重循环,时间复杂度为 (O(n^2)),其中 (n) 是数组的长度。对于较大的 (n),这种复杂度可能导致性能问题。

  • 空间复杂度:算法只使用了常量级的额外空间,所以空间复杂度为 (O(1))。