本文讲述了通过JAVA解决 AI刷题 21.环形数组中的最大贡献值
21.环形数组中的最大贡献值
问题描述:
小S拿到了一个长度为 nn 的环形数组,并定义了两个下标 ii 和 jj 的贡献值公式为:
f(i, j) = (a_i + a_j) × dist(i, j)
其中 dist(i, j) 是下标 ii 和 jj 在数组中的最短距离。小S希望找到一对下标,使得它们的贡献值尽可能大。环形数组的特点是最左和最右的元素也是相邻的。你需要帮助她找到最大贡献值。
例如,给定数组 [1, 2, 3],由于是环形数组,任意两个下标的距离都是1,因此 f(2,3)=(2+3)×1=5f(2,3)=(2+3)×1=5。
题目要求:
题目所给的函数声明为:public static int solution(int n, int[] a),即该函数接收int类型的数组长度n,以及对应的数组a[]。返回结果为最大贡献值,类型为int。
题目样例:
样例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
解析:
重点解析:
该题目的最难之处在于找到两个元素之间的最大距离。当数组为单项的时,距离为两个元素下标的差的绝对值r1。当数组为环形时,从两个方向寻找到另一个元素,两个距离之和刚好为环形数组元素的间隙数目,而物品在排放为环形时,其间隙数目和物品数目相同。因此,可以证明,反向距离r2与r1的关系为r1 + r2 == n,其中n为数组长度。
遍历数组:
解决了最难之处,我们便可以开始寻找解题方法。显然,我们可以通过二重循环的方式,利用两个变量来计算这两个下标对应元素的贡献值。具体代码如下:
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int r = Math.abs(j - i);
if (r > n - r) {
r = n - r;
}
int score = (a[i] + a[j]) * r;
}
}
寻找最大贡献值:
为了找到最大的贡献值,可以单独设置一个变量存储目前找到的最大贡献值。在循环中,不断与新的贡献值进行比较,当有新的贡献值比它大的时候,就可以替换为新的贡献值。直到最后,返回这个最大贡献值。
具体代码:
结合以上内容,得到最终的代码为:
public static int solution(int n, int[] a) {
int max = 0;
for (int i = 0; i < n; i++) {
for (int j = 0; j < n; j++) {
int r = Math.abs(j - i);
if (r > n - r) {
r = n - r;
}
int score = (a[i] + a[j]) * r;
if (score > max) {
max = score;
}
}
}
return max;
}