环形数组中的最大贡献值|豆包MarsCode AI刷题

90 阅读3分钟

问题描述

小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。


测试样例

样例1:

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

样例2:

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

分析思路

首先,我们需要理解环形数组的特点,即数组的首尾元素是相邻的。这意味着在计算两个下标之间的距离时,我们需要考虑两种情况:一种是直接距离,另一种是通过数组首尾相连的距离。具体来说,对于任意两个下标 ( i ) ( j ),它们的距离可以表示为 {dist}(i, j) = min(|j - i|, n - |j - i|)

为了找到最大贡献值,我们需要遍历数组中的所有可能的下标对 ( (i, j) ),计算每一对的贡献值,并记录其中的最大值。由于环形数组的特性,我们需要特别注意数组的边界情况。

解题步骤

  1. 初始化变量:定义一个变量 res 来存储最大贡献值,初始值为0。
  2. 遍历数组:使用两个嵌套的循环遍历数组中的所有下标对 ( (i, j) )。外层循环从0遍历到 ( n-1 ),内层循环从1遍历到 ( n )
  3. 计算距离:对于每一对下标 ( (i, j) ),计算它们的两种可能的距离:直接距离和通过数组首尾相连的距离 。取这两者的最小值作为最终距离。
  4. 计算贡献值:根据公式,计算当前下标对的贡献值。
  5. 更新最大值:如果当前贡献值大于res,则更新 res
  6. 返回结果:遍历结束后,返回 res 作为最大贡献值。

具体代码

    public static int solution(int n, int[] a) {
        int res = 0;
        for (int i = 0; i < n - 1; i++) {
            for (int j = 1; j < n; j++) {
                int dist1 = (j - i);
                int dist2 = (n - j + i);
                int dist = Math.min(dist1, dist2);
                int newres = (a[i] + a[j]) * dist;
                if (newres > res) {
                    res = newres;
                }
            }
        }
        return res; 
    }

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

总结

与普通数组不同,环形数组的首尾相连特性增加了计算距离的复杂性。通过对距离的两种情况进行比较,我们能够准确计算出最短距离,从而确保贡献值的计算是正确的。