Algorithm 子集和问题实例
我有一个问题,它是子集和问题的一个非常明显的例子: 给定[-6500065000]范围内的整数列表,如果列表的任何子集总和等于零,则函数返回true。否则返回False 我想问的更多的是一个解释,而不是一个解决方案 这是我在考虑问题的复杂性之前提出的一个特定于实例的解决方案Algorithm 子集和问题实例,algorithm,computer-science,np-complete,Algorithm,Computer Science,Np Complete,我有一个问题,它是子集和问题的一个非常明显的例子: 给定[-6500065000]范围内的整数列表,如果列表的任何子集总和等于零,则函数返回true。否则返回False 我想问的更多的是一个解释,而不是一个解决方案 这是我在考虑问题的复杂性之前提出的一个特定于实例的解决方案 对数组A[]进行排序,并在排序期间将每个元素和到计数器“extSum”(O(NLogN)) 定义指针low=A[0]和high=A[n-1] 以下是决定代码: while(A[low]0){ while(sum-A[高]0
- 对数组A[]进行排序,并在排序期间将每个元素和到计数器“extSum”(O(NLogN))
- 定义指针low=A[0]和high=A[n-1]
- 以下是决定代码:
while(A[low]0){ while(sum-A[高]
0){ 总和=tmp; 高--; } 否则{ 高--; } } extSum-=A[低]; 低++; 高=n-1; } 否则{ /*对称代码:开关低、高和操作>和<*/ } } 返回false;
这段代码的时间复杂度不是O(n^2)吗 我已经阅读了各种DP解决方案,我想了解的是,对于我所面临的问题的具体实例,它们比这种天真直观的解决方案要好多少。我知道我的方法可以改进很多,但在时间复杂度方面没有什么大的不同 谢谢你的澄清
EDIT:一个明显的优化是,在排序时,如果找到0,函数会立即返回true……但这只适用于数组中有0的特定情况。Hmm,我认为{0}会超过您的答案
因为它只会忽略while并返回false。嗯,我认为{0}会超过你的答案
因为它只会忽略while并返回false。如果我正确理解了您的代码,您不认为子集是连续的吗?这不一定是正确的case@isbadawi:嗯,我只是假设它会被排序,这是因为我将排序作为第一步。我的意思是,例如,如果你的输入是[-4,1,4],该怎么办。一个解决方案是{-4,4},但您不会找到it@isbadawi当前位置我想它确实找到了。。。如果输入为[-4,1,4],则extSum将为1。内部while的第一次运行将仅递减高(因为1-4<0),第二次运行将返回0:1-A[1]=0。。。。否?我只需要返回True或False,而不是实际的子集……如果我正确理解了您的代码,您不认为子集是连续的吗?这不一定是正确的case@isbadawi:嗯,我只是假设它会被排序,这是因为我将排序作为第一步。我的意思是,例如,如果你的输入是[-4,1,4],该怎么办。一个解决方案是{-4,4},但您不会找到it@isbadawi当前位置我想它确实找到了。。。如果输入为[-4,1,4],则extSum将为1。内部while的第一次运行将仅递减高(因为1-4<0),第二次运行将返回0:1-A[1]=0。。。。否?我只需要返回真或假,而不是实际的子集……嗯,是的,这是真的。但这是一个如此特殊的案例,我甚至没有提到。实际上,当我说“我知道我的方法可以改进很多”时,我想到的第一个优化是,当我对数组排序时,如果我找到任何0,我可以立即返回true。好吧,我认为如果你这样做,你就不必排序。考虑一个数组只保存负数和一个数组,只保存正和。你唯一要做的就是测试是否有一个和彼此相等。但它仍然是O(N^2),这里唯一的优点是不需要排序。可能是真的,但由于排序复杂度是O(NlogN),而DP复杂度更高,排序可能不是这里的瓶颈…对吗?这可能会失败{-4,-3,-2,6}?您只能使用一个数组。如果只有负数表示和加1,如果正数表示和加2,那么数组中等于3的数字就是你的答案。两个数组很容易给出这个想法。嗯,是的,这是真的。但这是一个如此特殊的案例,我甚至没有提到。实际上,当我说“我知道我的方法可以改进很多”时,我想到的第一个优化是,当我对数组排序时,如果我找到任何0,我可以立即返回true。好吧,我认为如果你这样做,你就不必排序。考虑一个数组只保存负数和一个数组,只保存正和。你唯一要做的就是测试是否有一个和彼此相等。但它仍然是O(N^2),这里唯一的优点是不需要排序。可能是真的,但由于排序复杂度是O(NlogN),而DP复杂度更高,排序可能不是这里的瓶颈…对吗?这可能会失败{-4,-3,-2,6}?您只能使用一个数组。如果只有负数表示和加1,如果正数表示和加2,那么数组中等于3的数字就是你的答案。两个数组很容易给出这个想法。
while(A[low]<0){
sum = extSum;
if(extSum>0){
while(sum - A[high] < sum){
tmp = sum - A[high];
if(tmp==0) return true;
else if(tmp > 0){
sum = tmp;
high--;
}
else{
high--;
}
}
extSum -= A[low];
low++;
high = n - 1;
}
else{
/* Symmetric code: switch low, high and the operation > and < */
}
}
return false;