题目分析
小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
思路
-
双重循环遍历:由于我们需要比较所有可能的 (i) 和 (j) 组合,最直接的方式是使用双重循环。外层循环遍历 (i),内层循环遍历 (j)(从 (i + 1) 开始),以确保 (i < j)。
-
计算表达式:在每次选择 (i) 和 (j) 时,计算 ((a[i] + a[j])) 和 (\min(j - i, n - j + i))。将这两者的乘积与当前的最大值进行比较,并更新最大值。
-
返回结果:遍历完成后,返回得到的最大值。
代码
下面是实现上述思路的代码:
#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;
}
代码分析
-
初始化:首先我们定义一个变量
res用于存储当前的最大值,初始值为0。 -
双重循环:外层循环遍历所有可能的 (i),内层循环从 (i + 1) 开始遍历 (j)。这样可以确保 (i < j)。
-
计算表达式:在内层循环中,我们计算表达式的值,并使用
max函数更新res。 -
返回结果:所有组合计算完成后,返回
res作为最终结果。
复杂度分析
-
时间复杂度:由于使用了双重循环,时间复杂度为 (O(n^2)),其中 (n) 是数组的长度。对于较大的 (n),这种复杂度可能导致性能问题。
-
空间复杂度:算法只使用了常量级的额外空间,所以空间复杂度为 (O(1))。