我有以下问题以及这次我做了一些R& D并得出了解决方案,但解决方案中存在一个小故障(一种情况)。
问:groupNoAdjacent递归问题::给定一个int数组,是否可以选择一些int的组,以便该组使用以下附加约束求和给定目标:如果数组中的值是如果选择在组中,则不能选择紧跟在数组中的值。 (不需要循环。)
groupNoAdj(0, {2, 5, 10, 4}, 12) => true --> This is true coz of 2+10 =12,NoAdjacency
groupNoAdj(0, {2, 5, 10, 4}, 14) => false -> 10+4=14,numbers are adjacent,its false
groupNoAdj(0, {2, 5, 10, 4}, 7) => false --> 2+5=7,numbers are adjacent,its false
我的解决方案如下所示。除了一个场景外,它适用于以下所有场景。
public boolean groupNoAdj(int start, int[] numbers, int target) {
start=0;
boolean[] reached = new boolean[target+1];
reached[0] = true;
for (int i=0;i<numbers.length;i++){
for (int j = i + 2; j<numbers.length; j++){
if(numbers[j] + numbers[i] == target){
reached[target]=true;
}else if(numbers[j] + numbers[i] < target){
numbers[i] = numbers[j] + numbers[i];
}
}
}
return reached[target];
}
情景如下:
Expected This Run
groupNoAdj(0, {2, 5, 10, 4}, 12) → true true OK
groupNoAdj(0, {2, 5, 10, 4}, 14) → false false OK
groupNoAdj(0, {2, 5, 10, 4}, 7) → false false OK
groupNoAdj(0, {2, 5, 10, 4, 2}, 7) → true true OK
groupNoAdj(0, {2, 5, 10, 4}, 9) → true true OK
groupNoAdj(0, {10, 2, 2, 3, 3}, 15) → true true OK
groupNoAdj(0, {10, 2, 2, 3, 3}, 7) → false false OK
groupNoAdj(0, {}, 0) → true true OK
**groupNoAdj(0, {1}, 1) → true false X**
groupNoAdj(0, {9}, 1) → false false OK
groupNoAdj(0, {9}, 0) → true true OK
groupNoAdj(0, {5, 10, 4, 1}, 11) → true true OK
我的代码不适用于BOLD中标记的那个。您想要给出的任何想法或输入或建议。我试过分析代码但是因为我没有得到特殊情况的解决方案我将它发布在Stackoverflow中
答案 0 :(得分:4)
public boolean groupNoAdj(int start, int[] nums, int target) {
if (target == 0)
return true;
if (start < nums.length)
return groupNoAdj(start + 2,nums,target - nums[start]) || groupNoAdj(start + 1,nums,target);
return false;
}
答案 1 :(得分:1)
因为这一行:
我从0开始,j初始化为0 + 2 = 2,但numbers.length为1,因此循环内的代码永远不会执行。
for (int j = i + 2; j<numbers.length; j++){
因为这一行,我从0开始,j初始化为0 + 2 = 2,但numbers.length是1,所以循环内的代码永远不会执行。
由于您使用布尔数组浪费了大量空间,因此您可以直接查找短数组。
if (numbers.length<1 && target==0){return true;)
一开始。然后,当您在目标中迭代列表时,这将起作用(我认为)。只要你可以为(0,{1,2} 1)返回true,那么基于你的测试用例看起来是可以接受的。
for (int i=0;i<numbers.length;i++){
for (int j=2;j<numbers.length;j++){
if (target-numbers[i]-numbers[j]==0){return true;}
}
if (target-numbers[i]==0){ return true;}
curr+=target[i];
}
return false;
答案 2 :(得分:1)
这是我的递归解决方案。
public boolean groupNoAdj(int start, int[] nums, int target)
{
if (start >= nums.length)
{
return target == 0;
}
if (groupNoAdj(start+1, nums, target - nums[start])
&& groupNoAdj(start+2, nums, target - nums[start]))
{
return true;
}
if (groupNoAdj(start+1, nums, target))
{
return true;
}
return false;
}
答案 3 :(得分:0)
这是一个没有循环的递归版本(在Scala中,但不是Java)。
val cases = List(
(0, List(2, 5, 10, 4), 12),
(0, List(2, 5, 10, 4), 14),
(0, List(2, 5, 10, 4), 7),
(0, List(2, 5, 10, 4, 2), 7),
(0, List(2, 5, 10, 4), 9),
(0, List(10, 2, 2, 3, 3), 15),
(0, List(10, 2, 2, 3, 3), 7),
(0, List[Int](), 0),
(0, List(1), 1),
(0, List(9), 1),
(0, List(9), 0),
(0, List(5, 10, 4, 1), 11))
for ((_,l, total) <- cases)
println(l.mkString("(", ",",")") + " " + makeTotal(l, total))
def makeTotal(l:List[Int], total:Int):Boolean = {
if (l.isEmpty)
total == 0
else
makeTotal(l.drop(1),total) || makeTotal(l.drop(2), total - l.head)
}
说明:
total
total
会减少此元素的值,我们需要从列表的其余部分创建新的总数,不包括下一个元素答案 4 :(得分:0)
如果你想看到一个简短的递归解决方案,这是我的:
public boolean groupNoAdj(int start, int[] nums, int target) {
if(target == 0) return true;
if(target < 0 || start >= nums.length) return false;
return groupNoAdj(start + 1, nums, target)
|| groupNoAdj(start + 2, nums, target - nums[start]);
}