在数组中查找具有最小差异和连续元素的 2 个子集

Posted

技术标签:

【中文标题】在数组中查找具有最小差异和连续元素的 2 个子集【英文标题】:Find 2 subsets in array that have minimum difference and consecutive elements 【发布时间】:2018-02-26 23:09:10 【问题描述】:

我遇到了一个我觉得很有趣的子集和问题的变体。因此,给定一个(正)元素数组,您必须将其划分为 2 组,以使它们的差异最小。但这就是问题所在。元素必须是连续的,并且它们也以循环顺序工作。这里有 2 个例子,你可以理解我的意思:

示例 1:

输入:7 5 1 3 8 9 11 8

输出:0(设置 1:11,8,7,设置 2:5,1,3,8,9

.


示例 2:

输入:10 14 75 90 3 5 40 4 8

输出:27(第 1 组:4,8,10,14,75,第 2 组:90,3,5,40)

使用 C++ 的可能解决方案是什么?谢谢!

【问题讨论】:

【参考方案1】:

线性时间解决方案使用两指针方法。目标参数是范围,其总和尽可能接近其余参数的总和。

将两个索引left, right 设置为数组开头。 csum 是数组范围 left..right-1 的当前总和。

如果再添加一个元素会使当前 cum 更接近理想值,则向右移动索引并更新参数。

当添加元素使当前总和变差时,开始删除左侧元素。

Delphi 代码仅返回最佳差异,范围本身((left,right-1) 对)可能在自己的 Min 操作实现中找到。

  function Nice(A: TArray<Integer>): Integer;
  var
    left, right, i, sum, csum, diff: Integer;
  begin
    sum := 0;
    for i := 0 to High(A) do
        sum := sum + A[i];

    left := 0;
    right := 1;
    csum := A[0]; //sum of current subsequence
    diff := Abs(sum - 2 * csum); //dif = Abs((sum - csum) - csum)
    result := diff;

    repeat

      //if adding right element makes difference better
      while (right < Length(A)) and (Abs(sum - 2 * (csum + A[right])) < diff) do begin
        csum := csum + A[right];
        diff := Abs(sum - 2 * csum);
        result := Min(result, diff);
        right := right + 1;
      end;

      repeat
        csum := csum - A[left];  //we always need at least one step
        diff := Abs(sum - 2 * csum);
        result := Min(result, diff);
        left := left + 1;
      until (left = right) or (Abs(sum - 2 * (csum - A[left])) >= diff);

    until (left = right);

  end;

【讨论】:

感谢您的宝贵时间!如果我们使用动态编程方法而不是直接的解决方案,这会更有效吗? 这种方法效率最高。它可能被视为一种 DP - 想象在左/右表中填充一些轨迹 好吧,我遇到了一个错误,程序返回 14 作为第二组的最佳差值,但答案是 27。有什么想法吗? @dituoa 函数找到优化参数 14 作为 halfsum 124 和 90..40 子序列和 138 的差。其余的有 sum 111,所以 138-111=27。我会写更正以返回您需要的值

以上是关于在数组中查找具有最小差异和连续元素的 2 个子集的主要内容,如果未能解决你的问题,请参考以下文章

在数组中查找最小值和最大值

查找最多具有 k 个奇数元素的不同连续子数组的数量

ArrayIndexOutOfBoundsException,同时找到数组中两个连续元素之间的最大差异

提高在具有许多条目设置为 np.inf 的二维 numpy 数组中查找最小元素的速度

在 numpy 数组中查找与所有其他行相比具有最小值的行

如何将一个数组划分为 K 个子数组,以使所有子数组中重复元素的数量之和最小?