如何解决给定一个由 n 个数字组成的数组,找出在它们之间插入“+”和“-”的所有方法,使表达式的结果为正
给定一组 n
数字,找出在它们之间插入 +
和 -
的所有方法,以便表达式的结果为正。
我最近发现了这个问题,我认为它很有趣,但我不确定如何解决它。我想我应该尝试回溯,不是吗? 任何帮助或提示深表感谢!
编辑:这会是一个正确的解决方案吗? (我用python写的)
def outputSolution(list):
print(list)
def solution(x,dim):
return len(x) == dim-1
def consistent(list,array):
partial_sum = array[0]
for i in range(len(list)):
if list[i] == 0:
partial_sum = partial_sum - array[i+1]
if list[i] == 1:
partial_sum = partial_sum + array[i+1]
absolute_remaining_sum = 0
for i in range(len(list)+1,len(array)): #the remaining elements in array
absolute_remaining_sum =absolute_remaining_sum + abs(array[i])
if partial_sum + absolute_remaining_sum < 0:
return False
else:
return True
def solve(list,array):
"""
array - the array of n given integers
list - the candidate to a solution
"""
dim = len(array)
for el in range(2): # el = 0 or 1 (0 for - and 1 for +)
if len(list) < dim - 1:
list.append(el)
if consistent(list,array):
if solution(list,dim):
outputSolution(list)
solve(list[:],array)
list.pop()
solve([],array)
我的思考过程是这些数字之间有 n-1 个差距。每个间隙中可以有一个“+”或“-”。所以我建立了一个列表,其中 list[i] 等于 0 如果在 array[i] 和 array[i+1] 之间有一个“-”,并且 list[i] 等于 0 如果在 array[i] 之间和 array[i+1] 有一个“+”。我生成了在列表中选择值的所有可能方法,然后我检查了该可能的候选者是否一致。而且我说如果加到给定数组剩余元素的最大和的部分和(使用我们当前列表中的 + 和 - 计算)是一个负数,那么候选是不一致的。如果候选是一致的,并且有要求的长度,那么我说它是一个解决方案。
例如,如果我将数组“array = [1,2,3,4,5,6,7]”作为输入,我会得到以下解决方案:
[0,1,1]
[0,0]
[0,1]
[1,0]
[1,1]
解决方法
回溯确实是一个合理的策略。由于您需要枚举,因此只有一种修剪技巧可以产生渐近差异。假设数组以一个非常大的负数开始,例如,
−50 10 10 10 10 1 2 3 4 5
总和始终包含 -50 项,因此每 10 项的符号必须为正,否则剩余的数字不足以使总和为正。通过扩大示例(越来越多的数字),我们可以在朴素回溯的复杂性和解决方案的数量之间创建指数级差距。
如果我们实现通常的深度优先回溯策略并保持剩余数组元素的绝对值之和,那么我们可以修剪每个部分和加上绝对值之和不为正的节点。由于每个未被剪枝的节点都会产生至少一个解决方案,我们最终会得到一个最优的输出敏感时间复杂度。
版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。