例如,给定类似4,10,4,7的序列,我们需要得到10.答案是4 + 10-4 = 10。建议使用什么样的方法。我可以用DP解决它吗?谢谢!
答案 0 :(得分:3)
我想到的最接近动态编程算法的是以下(Python):
def find_number(numbers, goal):
# sum 0 can be reached with empty sequence
found = {0: []}
# iterate over all numbers in the list
for n in numbers:
# update dict of found numbers with m+n and m-n for each m in found
found = dict([(m + n, path + [+n]) for (m, path) in found.items()] +
[(m - n, path + [-n]) for (m, path) in found.items()])
# check whether the goal number is among them
if goal in found:
return found[goal]
除了递归树遍历算法之外,这可能具有防止一些双重工作的优点,因为中间结果(可以在序列中达到某个数字的数字)存储在哈希映射中。 (也就是说,如果使用第一个k
数字的多个组合可以达到某个数字,则只有其中一个存储在地图中。)可以通过解除不可能达到目标的中间结果来进一步优化即使添加或减去所有剩余数字的总和。
尽管如此,正如递归方法一样,最坏情况的复杂性(时间和空间)甚至可能是平均情况复杂度仍然是列表长度的指数,因为found
的大小map可以在每次迭代中加倍。
答案 1 :(得分:1)
以下是JavaScript中的一个示例。如果需要,您可以更改序列中的数字。只有匹配时才会记录结果。
var sequence = [4, 10, 4, 7],
tree = []
for (var i=0; i<sequence.length; i++){
tree.push([sequence[i], -sequence[i]])
}
function findMatch(arr, match, numSoFar, path, iterations){
var numSofar1 = numSoFar + arr[iterations][0],
numSofar2 = numSoFar + arr[iterations][1],
path1 = path + (arr[iterations][0] > 0 && iterations > 0 ? "+" : "")
+ String(arr[iterations][0]),
path2 = path + (arr[iterations][1] > 0 && iterations > 0 ? "+" : "")
+ String(arr[iterations][1])
if (numSofar1 == match) console.log(path1)
else if (numSofar2 == match) console.log(path2)
else if (iterations < arr.length-1){
findMatch(arr, match, numSofar1, path1, iterations + 1)
findMatch(arr, match, numSofar2, path2, iterations + 1)
}
}
findMatch(tree, 10, 0, "", 0)