样本输入:
4 6 4 3 2 2 1 1
第一个数字=总数T(T <1000)
第二个数字=数字数S(S <= 12)
后面的S数字=数字的值(每个值<100)。 (可能会发生重复,输入的顺序是不递增的)
我的工作是使用列表中加起来为T的数字找到所有“不同的和”。
因此,该输入的示例输出为:
4
3+1
2+2
2+1+1
我的想法是逐一遍历列表,找到具有不同数字的所有数字组合,直到数字列表的大小-已评估的数字数量。您可以从每个组合中创建一个列表,然后将该列表添加到列表的HashSet中(HashSet可以防止重复)。
因此,您要检查所有1、2、3、4、5和6尺寸的组合,然后选择4种 然后将所有1、2、3、4、5个尺寸的组合与3搭配使用,而忽略4 然后将所有1、2、3、4大小的组合与2一起使用,而忽略4和3
等
答案 0 :(得分:1)
您应该尝试递归解决方案。通常,您只需要处理以下想法:对于每个数字,您都可以将其包括在总和中,也可以不包括。这意味着您正在构建数字的幂集,并且将得到O(2^N)
解决方案。
简短地使用伪代码:
def get_all_sums(arr, target):
result = []
def helper(index, current_arr, current_sum):
# once you've gone over the arr you can return. If all your numbers are positive
# you can also return early if the current_sum > target
if index == len(arr): return
# solution found - add it to the result
if current_sum == target: result.append(current_arr)
# include the current index
helper(index + 1, current_arr + [arr[index]], current_sum + arr[index])
# don't include the current index
helper(index + 1, current_arr, current_sum)
helper(0, [], 0)
# sort and hash to get rid of duplicates; return a set
return {tuple(sorted(i) for i in result)}
答案 1 :(得分:0)
可以通过简单的递归找到答案,我将使用问题中的示例进行演示。
在递归的第一级,要解决的问题是
target=4 count=6 allowed={4,3,2,2,1,1} chosen={}
第一层在循环中选择每个唯一值,然后进行递归调用。因此,来自第一级的递归调用是
target=0 size=5 allowed={3,2,2,1,1} chosen={4}
target=1 size=4 allowed={2,2,1,1} chosen={3}
target=2 size=3 allowed={2,1,1} chosen={2}
target=3 size=1 allowed={1} chosen={1}
此处的关键是在每个递归级别上,允许值的数组会变小。只能使用跟随所选值的那些值。因此,例如,当第一级递归选择值3时,则仅允许小于3的值。如果是重复项,则选择第一个重复项,并将允许的值限制为其余重复项和任何较小的值。
参数处于第二级递归时
target=0 size=5 allowed={3,2,2,1,1} chosen={4}
这是成功的基本情况:target
为0。在这种情况下,将{4}添加到输出列表,因为这是解决方案。
参数处于第二级递归时
target=1 size=4 allowed={2,2,1,1} chosen={3}
由于2大于目标,因此代码应跳过2。因此,唯一的递归调用是
target=0 size=1 allowed={1} chosen={3,1}
这也是基本情况,因此第三级递归会将<3,1}添加到输出中。
参数处于第二级递归时
target=2 size=3 allowed={2,1,1} chosen={2}
将有两个递归调用
target=0 size=2 allowed={1,1} chosen={2,2}
target=1 size=1 allowed={1} chosen={2,1}
第一个是基本情况,因此在输出中添加{2,2} 。另一个递归调用最终将将{2,1,1}添加到输出中。
参数处于第二级递归时
target=3 size=1 allowed={1} chosen={1}
有一个递归调用
target=2 size=0 allowed={} chosen={1,1}
这是失败的基本情况:target
不为零,size
为0。
请注意,以这种方式解决问题后,仅生成唯一的解决方案,因此无需删除重复的解决方案。
还请注意,最大递归深度由S
确定,因此将S
限制在一个合理的较小数字(S <= 12
则被视为合理的较小数字)非常重要。