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

133 阅读3分钟

环形数组中的最大贡献值

问题描述

给定一个长度为 n 的环形数组 a ,我们需要找到一对下标 (i, j) ,使得它们的贡献值 f(i, j) = (a_i + a_j) * dist(i, j) 最大,其中 dist(i, j) 是下标 i 和 j 在环形数组中的最短距离。

关键点

  1. 环形数组的距离计算

    • 对于环形数组,下标 ( i ) 和 ( j ) 的最短距离可以表示为: [ \text{dist}(i, j) = \min(|i - j|, n - |i - j|) ]
    • 这是因为在环形数组中,可以从两个方向到达另一个下标,取这两者中的最小值。
  2. 贡献值的计算

    • 贡献值 ( f(i, j) ) 为: [ f(i, j) = (a_i + a_j) \times \text{dist}(i, j) ]
    • 我们需要遍历所有可能的下标对 ( (i, j) ),计算它们的贡献值,并找到最大值。
  3. 特殊情况处理

    • 当数组长度 ( n ) 为1时,没有两个不同的下标,因此最大贡献值为0。

代码逻辑

  1. 特殊情况处理

    • 如果数组长度 ( n ) 为1,直接返回0。
      if (n == 1) {
          return 0;
      }
      
  2. 初始化最大贡献值

    • 使用 Integer.MIN_VALUE 初始化 maxContribution,确保任何有效的贡献值都能更新它。
      int maxContribution = Integer.MIN_VALUE;
      
  3. 双重循环遍历所有下标对

    • 外层循环遍历每个下标 ( i )。
    • 内层循环遍历每个下标 ( j ),确保 ( i ) 和 ( j ) 不相同。
      for (int i = 0; i < n; i++) {
          for (int j = 0; j < n; j++) {
              if (i != j) {
                  int distance = Math.min(Math.abs(i - j), n - Math.abs(i - j));
                  int contribution = (a[i] + a[j]) * distance;
                  maxContribution = Math.max(maxContribution, contribution);
              }
          }
      }
      
  4. 计算最短距离

    • 使用 Math.min(Math.abs(i - j), n - Math.abs(i - j)) 计算下标 ( i ) 和 ( j ) 在环形数组中的最短距离。
  5. 计算贡献值

    • 使用公式 (a[i] + a[j]) * distance 计算贡献值。
  6. 更新最大贡献值

    • 使用 Math.max 更新 maxContribution,确保记录下最大的贡献值。
  7. 返回结果

    • 最后返回 maxContribution

完整代码

public class Main {

    public static int solution(int n, int[] a) {
        // 特殊情况处理:数组长度为1
        if (n == 1) {
            return 0;
        }

        int maxContribution = Integer.MIN_VALUE;

        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                if (i != j) {
                    int distance = Math.min(Math.abs(i - j), n - Math.abs(i - j));
                    int contribution = (a[i] + a[j]) * distance;
                    maxContribution = Math.max(maxContribution, contribution);
                }
            }
        }

        return maxContribution;
    }

    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);
        System.out.println(solution(1, new int[]{9}) == 0); // 添加对单个元素数组的测试
    }
}

测试用例解释

  1. 样例1

    • 输入:n = 3, a = [1, 2, 3]
    • 输出:5
    • 解释:最短距离为1,最大贡献值为 (2 + 3) * 1 = 5
  2. 样例2

    • 输入:n = 4, a = [4, 1, 2, 3]
    • 输出:12
    • 解释:最大贡献值为 (4 + 3) * 2 = 14,但实际最大贡献值为 (4 + 2) * 3 = 18
  3. 样例3

    • 输入:n = 5, a = [1, 5, 3, 7, 2]
    • 输出:24
    • 解释:最大贡献值为 (7 + 5) * 3 = 36
  4. 样例4

    • 输入:n = 1, a = [9]
    • 输出:0
    • 解释:只有一个元素,没有两个不同的下标,因此最大贡献值为0。

感恩字节跳动,感恩MarsCode AI,感恩青训营❤