Algorithm 从给定集合中找出所有方法求和给定数(允许重复)
给定一个由n个元素组成的数组(例如[1,2])和一个数字“k”(例如6),找出所有可能的方法来生成sum=k 举个例子,答案是4,因为Algorithm 从给定集合中找出所有方法求和给定数(允许重复),algorithm,Algorithm,给定一个由n个元素组成的数组(例如[1,2])和一个数字“k”(例如6),找出所有可能的方法来生成sum=k 举个例子,答案是4,因为 1 1 1 1 1 1 1 1 1 1 2 1 1 2 2 2 2 2 我能想到的算法是用蛮力,我们模拟所有可能的场景,当给定的状态无法达到结果时停止 arr[] = [1,2] k = 6 globalCount =0; function findSum(arr,k) { if(k ==0) glob
1 1 1 1 1 1
1 1 1 1 2
1 1 2 2
2 2 2
我能想到的算法是用蛮力,我们模拟所有可能的场景,当给定的状态无法达到结果时停止
arr[] = [1,2]
k = 6
globalCount =0;
function findSum(arr,k)
{
if(k ==0)
globalCount++
return
else if(k<0)
return
for each i in arr{
arr.erase(i)
tmp = k
findSum(arr,tmp)
while(k>=0){
findSum(arr,tmp -= i)
}
}
arr[]=[1,2]
k=6
全球账户=0;
函数findSum(arr,k)
{
如果(k==0)
全球账户++
返回
else如果(k=0){
findSum(arr,tmp-=i)
}
}
我不确定我的解决方案是否是最有效的。请评论/更正或显示指向更好解决方案的指针
编辑:如果有人能告诉我我的代码及其soln代码的运行时复杂性,我将不胜感激。:)
我认为我的代码复杂度是Big-O(n^w)w=k/avg(arr[0]…arr[n-1])这是分区问题的一个有趣子集。如果允许所有整数,实际上有一个封闭形式的解决方案(请参见和) 搜索“受限配分函数”给了我一些线索。对这个问题的两个解决方案进行了非常严格的数学讨论
不幸的是,我太懒了,无法编写这些代码。它们是非常密集的解决方案。如果你愿意原谅那些花哨的linq技巧,你可能会发现这个C#解决方案很有用。幸运的是,林克读起来有点像英语。我们的想法是建立解决方案,因为
k
从0开始递增,直到它达到正确的值。k
的每个值都基于以前的解决方案。不过,你必须注意的一件事是,确保你找到的新“方式”不是对他人的重新排序。我解决这个问题的办法是,如果它们被分类,就把它们算作有效的。(这只是一个比较)
它使用动态规划方法,应该比简单的递归方法更快。我想。我知道它的速度足够快,可以在几毫秒内计算出打破一美元的方法的数量。(242)静态void填充subsetsum(int[]a,int K,int runSum,int idx,ArrayList ans,ArrayList al){
如果(idx>=a.length | | runSum>K)
返回;
if(runSum==K){
ans.add(新ArrayList(al));
返回;
}
ArrayList temp=新的ArrayList(al);
临时添加(a[idx]);
populateSubsetSum(a,K,runSum+a[idx],idx,ans,temp);//当允许元素的重复时
填充subsetsum(a、K、runSum、idx+1、ans、al);
}
将此函数称为:
populateSubsetSum(a,K,0,0,ans,new ArrayList<>());//array,sum,initial_sum,global 2d list,temp list
populateSubsetSum(a,K,0,0,ans,new ArrayList())//数组、总和、初始总和、全局2d列表、临时列表
代码的+1可能重复。天哪!如果你不告诉我,我永远都不会知道这是一个编译和执行的程序。这很像英语你能发布它的C或Python版本吗?感谢Queequeg发现问题背后的问题。:)
1 1 1 1 1 1
1 1 1 1 2
1 1 2 2
2 2 2
static void populateSubsetSum(int[]a,int K,int runSum,int idx,ArrayList<ArrayList<Integer>> ans,ArrayList<Integer> al){
if(idx>=a.length || runSum>K)
return;
if(runSum==K){
ans.add(new ArrayList<>(al));
return;
}
ArrayList<Integer> temp=new ArrayList<>(al);
temp.add(a[idx]);
populateSubsetSum(a,K,runSum+a[idx],idx,ans,temp);//when repitions of elements are allowed
populateSubsetSum(a,K,runSum,idx+1,ans,al);
}
populateSubsetSum(a,K,0,0,ans,new ArrayList<>());//array,sum,initial_sum,global 2d list,temp list