因此,我一直试图绕过递归,遇到了这个问题并陷入困境。 在这里...
我已经获得了一个元素数组和一个正整数,我必须找到通过添加array元素(仅使用每个元素一次)来获得正整数的方法的数量。
例如:
array = [1, 4, 9]
n = 10
所以答案将是1,即(1,9)
由于我已经很难理解递归了,请尝试阐述一下
这是我在解决问题时想到的,我也尝试使用循环来完成,但是也没有成功。
def _Sum(X, li):
if X == 0:
return 1
if X < 0:
return 0
if X > 0:
ways = 0
for i in range(len(li)):
ways += _Sum(X-li[i], li)
return ways
答案 0 :(得分:1)
由于您没有显示任何代码,因此我只是给您一个提示。如果您需要更多细节,请显示更多工作。我将忽略[0]
(有一种或两种方式?)和n == 0
(有空总和吗?)的歧义情况。
如果array
为空,则如果1
为零,则答案为n
,否则为0
。
如果array
有多个元素,则求和array
的子数组以得到值n
的方法的数量等于求和a的方法的数量。 array[1:]
的子数组以获得值n
(表示我们不使用总和中的array[0]
的值)加上求和{ {1}}来获得array[1:]
的值(这意味着我们确实在总和中使用了n - array[0]
的值)。
现在您已经显示了自己的代码,这是一个解决问题的例程。这确实将array[0]
返回为_Sum(0, [1])
,因为它将空总和计为求和为零的方式。如果您不喜欢这样做,请编写一个禁止0
为零的外部例程,然后调用我的例程。
有些例程可以避免递归,并且效率更高。还可以修改此例程以避免使用输入列表的一部分,以提高效率,但是编写的例程很简单。
X
为详细说明,请注意我的例程具有一个“基本案例”,该案例检查最简单的可能性。在这里,这意味着检查空白列表。如果特定调用不是基本情况,则我的代码将问题减少为一个或多个较小的问题。在这里,这意味着删除列表的第一个元素。在您的问题中,有两种方法可以获取总和以获取目标值:包括第一个列表值或将其忽略。因此,我们递归调用例程两次,并将两个结果相加。清楚吗?
最后,您问代码有什么问题。简而言之,您的算法是错误的。我不清楚您为什么认为该算法会起作用。基本上,您会不断从目标值中减去其中一个元素,直到它不再为正为止;如果该目标值恰好为零,则您要对方法数加1。但是,如果您看一下示例
def _Sum(X, li):
"""Return the number of sub-lists of list `li` that sum to `X`.
This assumes list `li` has only positive integers.
"""
if len(li) == 0:
if X == 0:
return 1
else:
return 0
else:
return _Sum(X, li[1:]) + _Sum(X - li[0], li[1:])
您的代码反复从print(_Sum(2, [1, 2])
中减去第一个值1
直到达到零,然后从2
中减去第二个值2
直到迅速达到零。这算作两种方式。
像我这样的工作算法需要同时更改目标值和列表,而不仅仅是目标值。您没有这样做,所以失败了。
答案 1 :(得分:0)
解决方案可能会根据预期的时间复杂度而有所不同。如果您只是想使其发挥作用(强力),我将给您一个提示。对于每个元素,您可以选择总和或忽略它。因此,您有2 ^ n种可能性。现在,您只需要以某种方式生成所有这些文件即可。您可以使用递归来实现。避免计数相同的东西是非常困难的。因此,让我们尝试使递归函数选择我们将要使用的第一个元素。然后,再次运行它,但使其选择的元素严格位于第一个元素之后,依此类推。看起来应该像这样:
Fun(prev, sum, value, array)
if(sum == value)
++result
for i from prev + 1 to size(array)
Fun(i, sum + array[i], value, array)
答案 2 :(得分:0)
我将创建数组项的每个组合并进行检查。
import itertools
def combinations(lst_items):
Combinations = []
for item in map(list, itertools.product([0, 1], repeat=len(lst_items))):
cCombo = [lst_items[index] for index,i in enumerate(item) if i == 1]
Combinations.append(cCombo)
return Combinations
def combo_matches(array, target):
return [i for i in combinations(array) if sum(i) == target]
combo_matches([1,4,9],10)
[[1, 9]]
combo_matches([1,2,3,4,5,6,7,8,9,10],15)
[[7, 8],
[6, 9],
[5, 10],
[4, 5, 6],
[3, 5, 7],
[3, 4, 8],
[2, 6, 7],
[2, 5, 8],
[2, 4, 9],
[2, 3, 10],
[2, 3, 4, 6],
[1, 6, 8],
[1, 5, 9],
[1, 4, 10],
[1, 3, 5, 6],
[1, 3, 4, 7],
[1, 2, 5, 7],
[1, 2, 4, 8],
[1, 2, 3, 9],
[1, 2, 3, 4, 5]]
答案 3 :(得分:0)
先前的答案是正确的,这是做同一件事的另一种方法,除了它不使用蛮力并且只对两个数字进行校验
#!/usr/local/bin/python
def sumsToTarget(arr, k):
arr.sort()
lhs = 0
rhs = len(arr)-1
while lhs < rhs:
sum = arr[lhs] + arr[rhs]
if sum == k:
print'sum of',arr[lhs],'and',arr[rhs],'is',sum
lhs += 1
elif sum < k:
lhs += 1
else:
rhs -= 1
arr = [8,6,5,2,4,1,9]
k = 10
sumsToTarget (arr,k)