如果给出一个子阵列[1,2,3,4]和值8.我想返回子阵列[1,3,4]。我的代码中有一个错误,我不确定如何修复它,因为我是新手递归。我的Python代码如下。我正在回复打印的值[3,4],这显然不是正确的答案。如何获得数组中的第一个元素?
def main():
s = 0
a = [1,2,3,4] # given array
sa = [] # sub-array
w = 8 # given weight
d = False
d, sa = checkForWeight(a,w,s,d,sa)
print sa
def checkForWeight(a,w,s,d,sa):
l = len(a)
s += a[0]
sa.append(a[0])
if s == w:
d = True
return d, sa
else:
try:
d, sa = checkForWeight(a[1:],w,s,d,sa)
if d != True:
d, sa = checkForWeight(a[2:],w,s,d,sa)
else:
return d, sa
except:
sa = [] # i put this here because I want to erase the incorrect array
return d, sa
答案 0 :(得分:1)
您需要任何子阵列与您的总和相匹配吗?还是所有子阵列? (或者是最短的还是最长的?)正确的答案将高度依赖于此。
顺便说一句,这是背包问题的一个变种:https://en.wikipedia.org/wiki/Knapsack_problem
此外,您的递归策略似乎是复杂的因素。 (如果是代码测试,单凭这可能会使申请人失败。)我强烈建议采用动态编程方法。
修改强>
如果您需要所有可能的,那么您正在查看NP问题。我建议专注于易于实施/维护,而不是绝对的表现来炫耀你的技能。例如:
import itertools
def find_all_subsets_that_sum(elements, total):
for i in range(len(elements)):
for possible in itertools.combinations(elements, i+1):
if sum(possible)==total:
yield possible
print list(find_all_subsets_that_sum([1,2,3,4,5,6,7,8,9,10], 10))
不是绝对最快的(你可以在自动递归解决方案中做很多修剪),但它与你提出的任何更复杂的解决方案都是相同的大O. (所有解决方案都将由O(n选择n / 2)主导。)很少有面试候选人会回答:
这并不像它可能的那么快,但它在最快的吐痰距离内,并且可能是开发时间内实施和维护的最佳投资回报率。当然,除非我们正在解析的数据集很大,在这种情况下,我建议放宽要求,以返回可以使用O(n ^ 2)动态编程解决方案计算的一些解决方案的启发式。“
你可以用它来脱颖而出。
答案 1 :(得分:1)
当前的问题是你在函数的顶部附加一个[0]到sa,但是后来用子调用的返回值来破坏它。要修补此问题,请在返回最终结果之前添加一个子句:
except:
sa = [] # i put this here because I want to erase the incorrect array
if d:
sa = [a[0]] + sa
print "Leave: drop", d,sa
return d, sa
我建议您遵循评论中的建议:不要传递太多东西,而是集中精力控制局部解决方案。
尝试两种方式的解决方案:使用和不使用当前元素。你的递归调用看起来像这样:
sa = checkForWeight(a[1:], w) # Solutions without first element
-- and --
sa = checkForWeight(a[1:], w-a[0]) # Solutions using first element
You don't have to return a success flag; if **sa** is None or empty, the call failed to find a solution. If it succeeded, in the **w-a[0]** call, then you also need to prepend each solution in **sa** with **a[0]**.
这会让你感动吗?
答案 2 :(得分:1)
我做了一个有效的递归解决方案,希望它有所帮助:
def main():
success, solution = WeightChecker((1,2,3,4)).check(8)
print solution
class WeightChecker(object):
def __init__(self, to_check):
self._to_check = to_check
def check(self, weight):
return self._check((), 0, weight)
def _check(self, current_solution, index_to_check, remaining_weight):
if remaining_weight == 0:
return True, current_solution
if index_to_check == len(self._to_check):
return False, ()
current_check = self._to_check[index_to_check]
success, solution = self._check(current_solution + (current_check, ), index_to_check + 1, remaining_weight - current_check)
if not success:
success, solution = self._check(current_solution, index_to_check + 1, remaining_weight)
return success, solution
(动态编程方法比keredson建议的更好)