核心Java编程中的groupoN邻接递归问题

时间:2010-12-20 08:53:35

标签: java recursion

我有以下问题以及这次我做了一些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中

5 个答案:

答案 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]);
  
  
}