你好我不是一个所谓的专业程序员。我有两个a1
和a2
integer
个数组,其中甚至长度 n
。我需要通过选择每个索引和一半的一个元素来找到a1
和a2
中元素的最小总和所选元素的em>应位于a1中,其余元素位于a2中。
示例:
a1 = [36, 72];
a2 = [35, 61];
结果应为97
,因为我们应从36
中选择a1
,从61
选择a2
。我认为一种解决方案是在n/2
和a1
中选择所有可能的 a2
元素并计算其结果。可以找到更高效的解决方案吗?
答案 0 :(得分:1)
选择所有可能的n / 2元素并寻找最小元素将起作用,但成本会非常高。特别是运行时复杂度将为O(n ^ n)。
基本思想是你想要在索引i处选择具有高差异|a1[i] - a2[i]|
的元素。所以这是一个算法草图:
d[i] = |a1[i] - a2[i]|
i
的降序索取d
索引。所以d
中最大元素的索引首先是d
中第二大元素的索引,依此类推。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]< A2 [2]。接下来你选择a2 [1](2),因为d [1]是d中的第二大元素。接下来你选择a1 [0](11)因为和以前一样的推理。最后,你意识到你已经从a1中选择了两个元素,这就是为什么你将所有剩余的元素从a2添加到你的总和(14)。结果因此是13 + 2 + 11 + 14 = 40
当有效实施时,这可以在O(n log n)
中运行答案 1 :(得分:1)
让我们的数组a1
和a2
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