具有一些额外条件的子集求和算法的复杂性
Complexity of Subset sum algorithm with some extra conditions
问题是关于通过以下调整查找整数数组中是否存在总和为目标的子集
- 必须包括所有 5 的倍数。
- 如果 1 后跟 5 的倍数,则不能包含它。
有一个
Standard solution
/*
* Given an array of ints, is it possible to choose a group of some of the ints,
* such that the group sums to the given target with these additional constraints:
* all multiples of 5 in the array must be included in the group.
* If the value immediately following a multiple of 5 is 1,
* it must not be chosen. (No loops needed.)
*
* groupSum5(0, {2, 5, 10, 4}, 19) → true
* groupSum5(0, {2, 5, 10, 4}, 17) → true
* groupSum5(0, {2, 5, 10, 4}, 12) → false
* groupSum5(0, {3, 5, 1}, 9) → false
* groupSum5(0, {2, 5, 4, 10}, 12) → false
* groupSum5(0, {3, 5, 1}, 5) → true
* groupSum5(0, {1, 3, 5}, 5) → true
* groupSum5(0, {1}, 1) → true
*/
public boolean groupSum5(int start, int[] nums, int target) {
if (start >= nums.length) return (target == 0);
if (nums[start] % 5 == 0) {
if (start < nums.length - 1 && nums[start + 1] == 1){
return groupSum5(start + 2, nums, target - nums[start]);
}
return groupSum5(start + 1, nums, target- nums[start]);
}
return groupSum5(start + 1, nums, target - nums[start])
|| groupSum5(start + 1, nums, target);
}
My Approach
public boolean groupSum5(int start, int[] nums, int target) {
final int len = nums.length;
if (start == len) {
return target == 0;
}
if (start > 0 && nums[start] == 1 && (nums[start- 1] % 5) == 0 ) {
return groupSum5(start + 1, nums, target);
}
if (groupSum5(start + 1, nums, target - nums[start])) {
return true;
} if ((nums[start] % 5) != 0
& groupSum5(start + 1, nums, target)) {
return true;
}
return false;
}
在时间复杂度方面,以上 2 项中哪一项的票价更好?
如果我没记错的话,标准解或第一个解的复杂度大于指数 (3^n) ?
我想如果我们考虑递归调用,那么说复杂度是 (4^n)?
是否正确?
我认为你的代码是错误的。 groupSum5(0, [0, 1, 1], 1) returns false 你的代码,因为两个 1 都被排除了。在最坏的情况下,正确的 groupSum5 和你的都是 O(2^n) 。尽管 groupSum5 在第一段代码中以文本形式出现了 4 次,但在单个堆栈帧中只能发生其中 2 次调用
问题是关于通过以下调整查找整数数组中是否存在总和为目标的子集
- 必须包括所有 5 的倍数。
- 如果 1 后跟 5 的倍数,则不能包含它。
有一个
Standard solution
/*
* Given an array of ints, is it possible to choose a group of some of the ints,
* such that the group sums to the given target with these additional constraints:
* all multiples of 5 in the array must be included in the group.
* If the value immediately following a multiple of 5 is 1,
* it must not be chosen. (No loops needed.)
*
* groupSum5(0, {2, 5, 10, 4}, 19) → true
* groupSum5(0, {2, 5, 10, 4}, 17) → true
* groupSum5(0, {2, 5, 10, 4}, 12) → false
* groupSum5(0, {3, 5, 1}, 9) → false
* groupSum5(0, {2, 5, 4, 10}, 12) → false
* groupSum5(0, {3, 5, 1}, 5) → true
* groupSum5(0, {1, 3, 5}, 5) → true
* groupSum5(0, {1}, 1) → true
*/
public boolean groupSum5(int start, int[] nums, int target) {
if (start >= nums.length) return (target == 0);
if (nums[start] % 5 == 0) {
if (start < nums.length - 1 && nums[start + 1] == 1){
return groupSum5(start + 2, nums, target - nums[start]);
}
return groupSum5(start + 1, nums, target- nums[start]);
}
return groupSum5(start + 1, nums, target - nums[start])
|| groupSum5(start + 1, nums, target);
}
My Approach
public boolean groupSum5(int start, int[] nums, int target) {
final int len = nums.length;
if (start == len) {
return target == 0;
}
if (start > 0 && nums[start] == 1 && (nums[start- 1] % 5) == 0 ) {
return groupSum5(start + 1, nums, target);
}
if (groupSum5(start + 1, nums, target - nums[start])) {
return true;
} if ((nums[start] % 5) != 0
& groupSum5(start + 1, nums, target)) {
return true;
}
return false;
}
在时间复杂度方面,以上 2 项中哪一项的票价更好?
如果我没记错的话,标准解或第一个解的复杂度大于指数 (3^n) ? 我想如果我们考虑递归调用,那么说复杂度是 (4^n)?
是否正确?我认为你的代码是错误的。 groupSum5(0, [0, 1, 1], 1) returns false 你的代码,因为两个 1 都被排除了。在最坏的情况下,正确的 groupSum5 和你的都是 O(2^n) 。尽管 groupSum5 在第一段代码中以文本形式出现了 4 次,但在单个堆栈帧中只能发生其中 2 次调用