给出一个整数数组和一个数字k。在数组中找到总计为k的元素的组合。最近我遇到一个编码问题,给我一个正整数A和k的数组。
让A = {4,15,7,21,2}并且k = 13 我的算法应该返回一个元素索引的列表,这些元素的总和为k。在这种情况下:[0,2,4]。每个元素只能使用一次。
我将如何解决这个问题?时间和空间的复杂性也将是什么。
答案 0 :(得分:2)
这是针对此问题的动态编程解决方案,我在transaction optimizer中将其编码为Emercoin。
算法思想:您创建[k + 1]个元素的数组。此数组中的索引是总和,可以由某个输入值达到,而具有数组的值-输入数,用于达到该总和。值-1表示,当前元素子集无法达到该总和。
让我们看看您的示例。在您的示例中,k = 13,我们首先从-1的14中创建数组DP:
DP =(-1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1)
空输出集(总和= 0)可以通过任何方式获得,因此,我们将一些非负数_1(例如-0)存入DP [0]。结果,DP [0] == 0 :
DP =(0 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1 -1)
此后,对于数组A [i]的所有输入值,请执行以下操作:
有一个主意:如果在先前的某个步骤中获得了总和“ j”,并且我们具有值A [i],则可以通过从a中添加第i个元素来达到总和“ j + A [i]”。数组A。
在我们的示例中,添加您的A [0] == 4之后,我们将获得DP:
DP =(0 -1 -1 -1 0 -1 -1 -1 -1 -1 -1 -1 -1 -1)
该零表示含义:A [0]可以达到总和“ 4”。
尝试添加A [1] =15。i= 1有两个可能的位置,DP [19]和dp [15]。两者都超出数组范围,所以我们只是不更新DP数组。
尝试添加A [2] =7。对于i = 2,有两个可能的位置,DP [11]和dp [7]。更新后,DP阵列将为:
DP =(0 -1 -1 -1 0 -1 -1 2 -1 -1 -1 2 -1 -1)
跳过A [3] == 21,与A [1]一样。
尝试添加A [4] =2。DP数组为:
DP =(0 -1 4 -1 0 -1 4 2 -1 4 -1 2 -1 4)
输入数组A []已耗尽,DP数组已准备好进行解释。我们看到,DP [13]> = 0,所以总和为13。 DP [13] == 4,所以A [4]达到总和“ 13”。记住它。将DP数组视为链表,其中值指向先前位置。因此,prev = 13-2 =11。我们看到,A [2]也包括在总和中。记住“ 2”。上一个位置:上一个= 11-7 =4。请参见DP [4]。有“ 0”。还要记住[0]。上一页= 4-4 =0。我们到达DP [0],停止解释。因此,我们在A [4,2,0]中收集了记住的索引。
问题解决了。