【説明】:
N 個の数値があり、それらの M の任意の組み合わせを加算すると、数値 X に等しくなります。これらの M 番号がどの番号の組み合わせであるかを要求します。このうち、M<=N であり、M の各組み合わせの数字は 1 回だけ出現します。
例: N 個の数値があります: [1、2、3、4、5、6、7、8、9]
必要数X:12
M、つまり考えられるすべての数値の組み合わせ ([3,9]、[4,8]、[5,7]、[1,4,9]...) を検索します。
Python で実装:
# 提供一个数组和目标的和
def solve(arr, target):
# 去重并排序
arr = list(set(arr))
arr.sort()
if target in arr:
print('1 : ',target)
for i in range(2, len(arr) + 1, 1):
resultArr = [] # 指定最终的数组用来存放该轮的结果(利用数组参数传的是数组的引用,最终结果数组是作为返回值来使用的
action(arr, 0, target, [], i, resultArr)
if len(resultArr):
print(i, resultArr)
# 整个数组、当前开始的索引、目标总额、当前的数组、需要多少个数、最终结果数组
def action(arr, startIndex, targetVal, curArr, totalNum, resArr):
tempIndex = startIndex
curArrLen = len(curArr) # 当前结果数组的长度
sumArr = sum(curArr) # 当前结果数组的总和
if startIndex == 0: # 第一次
# 下一个索引值存在,且当前数组中索引
while(len(arr) > tempIndex + 1 and arr[tempIndex] + arr[tempIndex + 1] + sumArr <= targetVal):
temparr = []
temparr.append(arr[tempIndex])
action(arr, tempIndex + 1, targetVal, temparr, totalNum, resArr)
tempIndex += 1
else:
# 只差一个数就满足条件
if curArrLen == totalNum - 1:
# 直接看那个所需要的数是否在数组中当前索引后面的范围内
contain = (targetVal - sumArr) in arr
if contain and arr.index(targetVal - sumArr) >= tempIndex:
# 如果数组中有该值,且是当前索引,或在其后,将该值加入到结果数组中,并将结果数组加到最终数组中
curArr.append(targetVal - sumArr)
resArr.append(curArr)
# 仍差大于一个以上的数
elif (curArrLen < (totalNum - 1)):
while(len(arr) > tempIndex + 1 and arr[tempIndex] + arr[tempIndex + 1] + sumArr <= targetVal):
t = [e for e in curArr]
t.append(arr[tempIndex])
action(arr, tempIndex + 1, targetVal, t, totalNum, resArr)
tempIndex += 1
簡単なテスト:
arr = [1,2,3,4,5,6,7,8,9]
target = 12
solve(arr, target)
結果: