环形数组中的最大贡献值

99 阅读4分钟

问题描述

小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

样例3:

输入:n = 5,a = [1, 5, 3, 7, 2]
输出:24 好的,让我们来逐步解决这个问题。首先,我们需要理解环形数组的特性,即数组的首尾是相连的。因此,计算两个下标之间的最短距离时,需要考虑两种情况:

  1. 直接计算两个下标之间的距离。
  2. 计算从数组末尾绕回到数组开头的情况。

接下来,我们需要遍历所有可能的下标对 (i, j),并计算它们的贡献值 f(i, j)。为了找到最大贡献值,我们可以使用两层循环来遍历所有可能的下标对。

以下是一些代码提示,帮助你实现这个算法:

java

public class Main {

    public static int 

    solution(int n, 

    int[] a) {

        int 

        maxContributio

        n = 0;

        // 遍历所有可能

        的下标对 (i, j)

        for (int i = 

        0; i < n; i

        ++) {

            for (int 

            j = 0; j 

            < n; j++) 

            {

                if (i 

                != j) 

                {

                    //

                     

                    计

                    算

                    下

                    标

                     

                    i 

                    和

                     

                    j 

                    之

                    间

                    的

                    最

                    短

                    距

                    离

                    in

                    t 

                    di

                    st

                     

                    = 

                    Ma

                    th

                    .

                    mi

                    n

                    (M

                    at

                    h.

                    ab

                    s

                    (i

                     

                    - 

                    j)

                    , 

                    n 

                    - 

                    Ma

                    th

                    .

                    ab

                    s

                    (i

                     

                    - 

                    j)

                    );

                    //

                     

                    计

                    算

                    贡

                    献

                    值

                     f

                    (i

                    , 

                    j)

                    in

                    t 

                    co

                    nt

                    ri

                    bu

                    ti

                    on

                     

                    = 

                    (a

                    [i

                    ] 

                    + 

                    a

                    [j

                    ])

                     

                    * 

                    di

                    st

                    ;

                    //

                     

                    更

                    新

                    最

                    大

                    贡

                    献

                    值

                    ma

                    xC

                    on

                    tr

                    ib

                    ut

                    io

                    n 

                    = 

                    Ma

                    th

                    .

                    ma

                    x

                    (m

                    ax

                    Co

                    nt

                    ri

                    bu

                    ti

                    on

                    , 

                    co

                    nt

                    ri

                    bu

                    ti

                    on

                    );

                }

            }

        }

        return 

        maxContributio

        n;

    }

    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);

    }

}

代码解释:

  1. 遍历所有可能的下标对:我们使用两层循环来遍历所有可能的下标对 (i, j)
  2. 计算最短距离:我们使用 Math.min(Math.abs(i - j), n - Math.abs(i - j)) 来计算下标 i 和 j 之间的最短距离。
  3. 计算贡献值:我们使用公式 (a[i] + a[j]) * dist 来计算贡献值。
  4. 更新最大贡献值:我们使用 Math.max 来更新最大贡献值。

代码解析

java

public class Main {

    public static int 

    solution(int n, 

    int[] a) {

        int 

        maxContributio

        n = 0;

        // 遍历所有可能

        的下标对 (i, j)

        for (int i = 

        0; i < n; i

        ++) {

            for (int 

            j = 0; j 

            < n; j++) 

            {

                if (i 

                != j) 

                {

                    //

                     

                    计

                    算

                    下

                    标

                     

                    i 

                    和

                     

                    j 

                    之

                    间

                    的

                    最

                    短

                    距

                    离

                    in

                    t 

                    di

                    st

                     

                    = 

                    Ma

                    th

                    .

                    mi

                    n

                    (M

                    at

                    h.

                    ab

                    s

                    (i

                     

                    - 

                    j)

                    , 

                    n 

                    - 

                    Ma

                    th

                    .

                    ab

                    s

                    (i

                     

                    - 

                    j)

                    );

                    //

                     

                    计

                    算

                    贡

                    献

                    值

                     f

                    (i

                    , 

                    j)

                    in

                    t 

                    co

                    nt

                    ri

                    bu

                    ti

                    on

                     

                    = 

                    (a

                    [i

                    ] 

                    + 

                    a

                    [j

                    ])

                     

                    * 

                    di

                    st

                    ;

                    //

                     

                    更

                    新

                    最

                    大

                    贡

                    献

                    值

                    ma

                    xC

                    on

                    tr

                    ib

                    ut

                    io

                    n 

                    = 

                    Ma

                    th

                    .

                    ma

                    x

                    (m

                    ax

                    Co

                    nt

                    ri

                    bu

                    ti

                    on

                    , 

                    co

                    nt

                    ri

                    bu

                    ti

                    on

                    );

                }

            }

        }

        return 

        maxContributio

        n;

    }

    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);

    }

}

代码结构

  1. 类定义

    • public class Main:定义了一个公共类 Main
  2. 方法定义

    • public static int solution(int n, int[] a):这是一个静态方法,接受两个参数:n 表示数组的长度,a 表示数组本身。该方法返回最大贡献值。
  3. 变量定义

    • int maxContribution = 0;:初始化最大贡献值为 0。
  4. 双层循环

    • for (int i = 0; i < n; i++):外层循环遍历数组中的每一个元素,i 表示当前元素的下标。
    • for (int j = 0; j < n; j++):内层循环遍历数组中的每一个元素,j 表示当前元素的下标。
    • if (i != j):确保 i 和 j 不是同一个下标。
  5. 计算最短距离

    • int dist = Math.min(Math.abs(i - j), n - Math.abs(i - j));:计算下标 i 和 j 之间的最短距离。这里考虑了环形数组的特性,即数组的首尾相连。
  6. 计算贡献值

    • int contribution = (a[i] + a[j]) * dist;:根据题目给出的公式 f(i, j) = (a_i + a_j) × dist(i, j) 计算贡献值。
  7. 更新最大贡献值

    • maxContribution = Math.max(maxContribution, contribution);:使用 Math.max 函数更新最大贡献值。
  8. 返回结果

    • return maxContribution;:返回计算得到的最大贡献值。
  9. 主方法

    • public static void main(String[] args):主方法用于测试 solution 方法。它调用 solution 方法并打印结果,验证是否与预期结果一致。

代码逻辑

  1. 遍历所有可能的下标对:通过两层循环,遍历数组中的所有可能的下标对 (i, j)
  2. 计算最短距离:根据环形数组的特性,计算下标 i 和 j 之间的最短距离。
  3. 计算贡献值:根据题目给出的公式,计算每个下标对的贡献值。
  4. 更新最大贡献值:在每次计算贡献值后,更新最大贡献值。
  5. 返回最大贡献值:最终返回计算得到的最大贡献值。