【问题标题】:Minimum sum of two arrays choosing half of the elements in each两个数组的最小和,每个数组中选择一半的元素
【发布时间】:2017-12-15 10:29:09
【问题描述】:

您好,我不是所谓的专业程序员。我有两个数组a1a2integers 具有相同的偶数长度 n。我需要通过为每个索引一半选择一个元素来找到a1a2中元素的最小总和选定的元素应位于 a1 中,其余元素应位于 a2 中。

示例

 a1 = [36, 72];  
 a2 = [35, 61];

结果应该是97,因为我们应该从a1 中选择36,从a2 中选择61。我认为一种解决方案是在a1a2 中选择所有可能的 n/2 元素并计算它们的结果。能否找到更有效的解决方案?

【问题讨论】:

  • 欢迎来到 Stack Overflow!查看如何创建 How to create a Minimal, Complete, and Verifiable 示例,以便您可以更好地回答您的问题。
  • 通常的方法是使用一个循环并检查索引是偶数还是奇数。由于没有索引检查和分支错误预测,两个单独的循环可能会更高效一些,但更有可能因一个错误而关闭。

标签: arrays algorithm


【解决方案1】:

让我们表示数组a1a2

    a1 = [36, 72];  
    a2 = [35, 61];

以不同的方式:我们组合第 i 个索引并计算 penalty = a2[i] - a1[i]

    a = [(36, 35; penalty = -1), (72, 61; penalty = -11)]

这里penalty是我们选择a2值而不是a1时必须付出的代价。让我们按罚分排序

    a = [(72, 61; penalty = -11), (36, 35; penalty = -1)]

现在让我们选择惩罚最低的n/2物品,取a2物品;选择惩罚最高的n/2物品,并选择a1物品:

    a = [(72, 61; penalty = -11), (36, 35; penalty = -1)]
         (72, 61; penalty = -11) - lowest,  take a2 item - 61
         (36, 35; penalty = -1)  - highest, take a1 item - 36

时间复杂度为O(n * log(n)) - 排序。

C# 实现:

  using System.Linq;

  ...

  int[] a1 = new int[] { 36, 72 };
  int[] a2 = new int[] { 35, 61 };

  var result = Enumerable
    .Range(0, a1.Length)
    .Select(i => new {
      v1 = a1[i],
      v2 = a2[i],
    })
    .OrderByDescending(item => item.v1 - item.v2)
    .Select((item, index) => index >= a1.Length / 2 
       ? item.v1 
       : item.v2)
    .Sum();

  Console.WriteLine(result);

结果:

  97

【讨论】:

  • 谢谢你,你的回答很有帮助也很聪明。
【解决方案2】:

选择所有可能的 n/2 元素并寻找最小值会起作用,但成本会很高。特别是运行时复杂度将是 O(n^n)。

基本思想是你要选择索引 i 处具有很大差异|a1[i] - a2[i]| 的元素。所以这里是一个算法的草图:

  1. 构建一个新数组 d 其中d[i] = |a1[i] - a2[i]|
  2. 现在以d 的降序获取索引i。所以d中最大元素的索引首先是d中第二大元素的索引,依此类推。
  3. 对于您从第 2 步获得的每个索引 i。取较小的元素 a1[i]a2[i] 并将其添加到您的总和中。您还将跟踪从a1 获取的元素数量以及从a2 获取的元素数量。如果在某一时刻您选择了 n/2 中的任何一个,您将用另一个数组中的剩余条目填充总和。

例子:

a1 = [11, 12, 13, 12]

a2 = [15, 2,  30, 14]

d  = [4 , 10, 17, 2]

所以这里首先选择 a1[2] (13),因为 d[2] 是 d 中最大的元素,并且 a1[2]

如果有效实施,这可以在 O(n log n) 中运行

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-19
    • 1970-01-01
    • 2020-03-20
    相关资源
    最近更新 更多