数组中 N 个元素的绝对差的最大和

Posted

技术标签:

【中文标题】数组中 N 个元素的绝对差的最大和【英文标题】:Largest sum from absolute differences of N elements in an array 【发布时间】:2019-11-08 16:26:36 【问题描述】:

这不是真正的作业,而是练习和优化,但这似乎是这类问题的最佳部分。

这是一个动态规划问题,具体如下:

-给定一个由N个元素组成的未排序数组,从中挑选出K个元素,使它们的绝对差最大。

此处计算相邻元素之间的绝对差值。因此,如果我们有一个包含 5 个元素的数组:1 5 3 2 1,并且 k = 3,那么绝对差异将是:

1 5 3 = |5-1| + |3-5| = 6

1 5 2 = |5-1| + |2-5| = 7

1 5 1 = [5-1| + |1-5| = 8

1 5 1 是最大的,需要 8 个

到目前为止,我尝试通过递归找到所有可能的 K 数组合,然后返回最大的(蛮力)来解决这个问题。

这是一个糟糕的想法,因为当尝试使用 N=50 和 k=25 的数组时,例如,有 1.264106064E+14 组合。

我使用的递归是一种简单的递归方法,用于打印数组中的所有 K 位整数,而不是打印它们,而是将它们保存在数组中:

static void solve(int[] numbers, int k, int startPosition, int[] result) 
        if (k == 0) 
            System.out.println(absoluteDifferenceSum(result));
            return;
        
        for (int i = startPosition; i <= numbers.length - k; i++) 
            result[result.length - k] = numbers[i];
            solve(numbers, k - 1, i + 1, result);
        
    

我想要实现的是最佳复杂度(我想这里不能低于 O(n^2),但我没有想法,不知道如何开始。感谢任何帮助!

【问题讨论】:

codereview.stackexchange.com/tour 【参考方案1】:

通常,我们可以有一个简单的O(n^2 * k) 公式,其中f(i, k) 表示当ith 元素在选择中最右边时选择k 元素的最佳结果,

f(i, k) = max(
  f(j, k - 1) + abs(Ai - Aj)
)
for all j < i

我们可以扩展至

  max( f(j, k - 1) + Ai - Aj )
= Ai + max(f(j, k - 1) - Aj)

when Ai >= Aj

  max( f(j, k - 1) + Aj - Ai )
= -Ai + max(f(j, k - 1) + Aj)

when Ai < Aj

由于正确的加数独立于Ai,我们可以构建一棵树,其节点既存储f(j, k - 1) - Aj,也存储f(j, k - 1) + Aj。此外,我们将在每个节点中存储每个子树的最大值。我们需要O(k) 树。当我们到达最后一个元素时,让我们跳到检查 k = 2 的树:

1

5 -> 4 -> (-1, 9)

3 -> 2 -> (-1, 5)

2 -> 3 -> (-1, 5)

3 -> (-3, 5)

tree for k = 2 so far:

   3 (-1, 5)
  /         \
2 (-1, 5)   5 (-1, 9)

1 is less than 3 so we first add -1
to the max for the right subtree
stored for f(j, k - 1) + Aj

-1 + 9 = 8
(note that this represents 1,5,1)

then we continue left in the tree
and compare 8 to a similar calculation
with node 2: -1 + 5 = 4
(note that this represents 5,2,1)

这样,我们可以将时间复杂度降低到O(n log n * k),空间为O(n * k)

【讨论】:

谢谢你的详细解释,试试这个!

以上是关于数组中 N 个元素的绝对差的最大和的主要内容,如果未能解决你的问题,请参考以下文章

51nod 1270 数组的最大代价

51nod 1270 数组的最大代价

51nod 1270 数组的最大代价

通过重新排列数组来最大化数组绝对差的总和

Leetcode: . 存在重复元素 III

Leetcode 220.存在重复元素III