【问题标题】:how to call a recursion call N number of times, given the number N?给定数字N,如何调用N次递归调用?
【发布时间】:2023-03-11 20:16:02
【问题描述】:

我有一个数字数组:S= {4,5},我想检查该组是否创建了 sum = 13

在这种情况下,是的:4 + 4 + 5 = 13

另一个例子:s={4,5}sum = 6 ->

我写了一个递归函数来解决这个问题:

public static boolean isSumOf(int [] s,int n)
    {
        if(n == 0)
            return true;
        if(n < 0)
            return false;

        return isSumOf(s,n-s[0]) || isSumOf(s,n-s[1]);
    }

但此函数仅适用于数组中的 2 个数字。 我需要编写一个递归函数来处理 N 个数字,例如 {4,9,3}{3,2,1,7} 等。

我不确定我该怎么做?如何根据数组的长度调用递归 N 次?或者也许我应该完全改变我的算法? 另外 - 我不允许使用循环。

【问题讨论】:

  • @JanKhonski 数组没有排序,而且情况也不一样,因为他只检查每个值一次,我可以有一个重复的数字

标签: java arrays recursion


【解决方案1】:
return isSumOf(s,n-s[0]) || isSumOf(s,n-s[1]);

您可以像这样用循环概括这个:

for (int i = 0; i < s.length; ++i) {
  if (isSumOf(s,n-s[i])) return true;
}
return false;

但是,由于不能使用循环,因此可以将等效循环编写为另一种递归方法:

boolean withoutLoop(int [] s,int n, int i) {
  if (i >= s.length) return false;
  return isSumOf(s,n-s[i]) || recurse(s, n, i+1);
}

然后从您的 isSumOf 方法中这样调用它:

public static boolean isSumOf(int [] s,int n)
{
    if(n == 0)
        return true;
    if(n < 0)
        return false;

    return withoutLoop(s, n, 0);  // Change here.
}

或者,如果你想写得更简洁:

return (n == 0) || (n < 0 && withoutLoop(s, n, 0));

【讨论】:

    【解决方案2】:

    这应该可行:

    public static boolean isSumOf(int [] s,int n)
        {
            if(n == 0)
                return true;
            if(n < 0)
                return false;
    
            for (int x: s) {
                if (isSumOf(s, n-x)) {
                    return true;
                }
            }
            return false;
        }
    

    更新:

    哦!没有循环,只有递归,你需要一个额外的参数:

    public static boolean isSumOf(int [] s,int n)
        {
            if(n == 0)
                return true;
            if(n < 0)
                return false;
    
            return isSum2(s, n, 0);
        }
    
    public static boolean isSum2(int [] s,int n,int i)
        {
            if (i >= s.length)
                return false;
    
            return isSumOf(s,n-s[i]) || isSum2(s,n,i+1);
        }
    

    【讨论】:

      【解决方案3】:

      分解问题:

      1. 数字相加
      2. 总和是否等于 13?

      然后想办法表达将数组求和为递归任务;例如元素 1 到 N 的总和是元素 1 + 元素 2 到 N 的总和。

      最后,将这个想法/表达转化为代码。

      【讨论】:

        【解决方案4】:

        对于任何递归问题,使用模板:

        ResultType recursiveMethod(params) {
             if( /* this is the simplest case */ ) {
                 return answer for the simplest case
             } else {
                 partialResult = solve part of the problem
                 resultForRest = recursiveMethod(rest of problem)
             }
        }
        

        特别是对于列表处理,这变成:

        if(list is empty) {
            return solution for an empty list
        } else {
            r = call self recursively for tail of list
            return solution for head of list combined with r
        }
        

        (其中“head”是第一项,“tail”是其余项。tail可能为空。)

        对于你的问题,最简单的情况是一个空数组:

         if(s.length == 0) {
              return n == 0;
         }
        

        对于else,“问题的一部分”是s[0],“问题的其余部分”是s[1] 以上。

         ... 
         } else {
             int head = s[0];
             int[] tail = Arrays.copyOfRange(s,1,s.length-1);
             return isSumOf(tail, n - head);
         }
        

        如果您直接使用List 而不是数组,那么代码会更简洁(并且可能更高效),因为您可以使用List.subList() 而不是copyOfRange()

        您也可以每次都传递整个数组,以及一个额外的参数,指示数组的多少。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 2016-08-06
          • 2017-04-30
          • 2011-05-23
          • 2023-03-16
          • 1970-01-01
          • 2013-02-23
          • 2020-08-25
          • 2020-01-18
          相关资源
          最近更新 更多