[英]Given an array of integers and a sum, the task is to find if there exists a subsets of given array with sum equal to given sum
Here is the function that i have written.这是我写的函数。
public static boolean existsSum(int[] arr, int n, int sum){
if(sum==0)
return true;
if(n<=0)
return false;
if(arr[n-1] == sum)
return true;
if(sum<0)
return false;
if(sum<arr[n-1])
return existsSum(arr, n-1,sum);
return existsSum(arr, n-1, sum-arr[n-1]) || existsSum(arr, n-1,sum) ;
}
This works perfectly fine.这工作得很好。 But as soon as I change last line of code like this
但是一旦我像这样更改最后一行代码
public static boolean existsSum(int[] arr, int n, int sum){
if(sum==0)
return true;
if(n<=0)
return false;
if(arr[n-1] == sum)
return true;
if(sum<0)
return false;
if(sum<arr[n-1])
return existsSum(arr, n-1,sum);
return existsSum(arr, n-1,sum) || existsSum(arr, n-1, sum-arr[n-1]) ;
}
It exceeds the time limit.它超过了时间限制。 I can't understand what is the impact on execution time upon changing the sequence.
我无法理解更改序列对执行时间有何影响。 Please help.
请帮忙。
Note the fact that ||
请注意
||
is short-circuiting ie in a || b
是短路的,即在
a || b
a || b
, if a
is true, b
is not evaluated. a || b
,如果a
为真,则不评估b
。
The difference between the two operands of ||
||
两个操作数的区别is that existsSum(arr, n-1, sum-arr[n-1])
"adds" the current item to the list of items that sums to the total sum, while existsSum(arr, n-1, sum)
doesn't.是
existsSum(arr, n-1, sum-arr[n-1])
将当前项“添加”到总和为总和的项列表中,而existsSum(arr, n-1, sum)
没有'吨。
In the first code snippet, if existsSum(arr, n-1, sum-arr[n-1])
is true, existsSum(arr, n-1, sum)
is not even called.在第一个代码片段中,如果
existsSum(arr, n-1, sum-arr[n-1])
为真,则existsSum(arr, n-1, sum)
甚至不会被调用。 Imagine I call this with the array [1,2,3]
and the sum 6. The first operand is going to return true every recursive call, and there is no need to evaluate the second operand.想象一下,我用数组
[1,2,3]
和总和 6 调用它。第一个操作数将在每次递归调用时返回 true,并且不需要评估第二个操作数。
Similarly, in the second code snippet, existsSum(arr, n-1, sum)
is run first, and if true, existsSum(arr, n-1, sum-arr[n-1])
is not called.类似地,在第二个代码片段中,
existsSum(arr, n-1, sum)
,如果为真, existsSum(arr, n-1, sum-arr[n-1])
。 However, existsSum(arr, n-1, sum)
can rarely return true on its own .但是,
existsSum(arr, n-1, sum)
很少会自行返回 true 。 What I mean by this is that for the call existsSum(arr, n-1, sum)
to return true, the value true
must have come from a recursive call to existsSum(arr, n-1, sum-arr[n-1])
.我的意思是,要使调用
existsSum(arr, n-1, sum)
返回true,则值true
必须来自对existsSum(arr, n-1, sum-arr[n-1])
的递归调用existsSum(arr, n-1, sum-arr[n-1])
。 You can verify this by analysing the different branches.您可以通过分析不同的分支来验证这一点。 (the two branches that return true are
sum==0
and arr[n-1] == sum
. Hopefully you'll agree both are rare) This means that backtracking (ie calling existsSum(arr, n-1, sum-arr[n-1])
) will definitely happen for existsSum(arr, n-1, sum)
. (返回 true 的两个分支是
sum==0
和arr[n-1] == sum
。希望你会同意两者都是罕见的)这意味着回溯(即调用existsSum(arr, n-1, sum-arr[n-1])
) 肯定会发生在existsSum(arr, n-1, sum)
。
In the worst case though, these two code snippets are the same.但在最坏的情况下,这两个代码片段是相同的。
This should be O(n)这应该是 O(n)
public static boolean sumExists(int [] in, int sum) {
//You might be able to get away with just sorting the values and not copying it.
int [] input = Arrays.copyOf(in, in.length);
Arrays.sort(input);
int currentSum = 0;
int startIdx = 0;
for (int i = 0; i < input.length; i++) {
if (currentSum > sum) {
while (currentSum > sum && startIdx < i) {
currentSum -= input[startIdx++];
}
}
if (currentSum == sum) {
return true;
}
currentSum += input[i];
}
return false;
}
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.