【问题标题】:Setting numbers from 1 to chosen number using recursion only仅使用递归将数字从 1 设置为所选数字
【发布时间】:2019-01-07 13:19:30
【问题描述】:

连续大约 7 小时后,我真的需要一些帮助,我需要从递归返回 选项数量,可以通过将数字从 1 设置为选择的数字(最大数字),它是禁止使用循环/数组,只能递归,数字都是正数(大于 0)并且只会更正数,例如:好的一个:{1,2},坏的一个:{2,1}。

示例:

n = 3 , max = 2 

n :应该在行中的数字 , max : 行中的最大数量。

{1,1,1}
{1,1,2}
{1,2,2}
{2,2,2}

从那个应该返回 4 的示例中,因为有 3 个数字的 4 个选项,它们的值最大为 2。

另一个:

n=2
max=3

{1,1}
{1,2}
{1,3}
{2,2}
{2,3}
{3,3}

从该示例中它应该返回 6,因为有 6 个选项。

【问题讨论】:

  • 连续写了大约 7 个小时之后,到目前为止你写了什么?
  • @NicholasK 我用数组写了几个小时,然后注意到它是被禁止的,现在我完全糊涂了,我什至不知道如何开始。
  • 对我来说听起来像是置换操作。
  • 嗯,添加您的尝试会有所帮助,帮助会更容易。到目前为止,这太宽泛了。

标签: java recursion


【解决方案1】:

如果没有先验知识,即使对于经验丰富的数学家来说,这也可能是一个具有挑战性的问题。它是multisets 的计数,它是组合数学的基本组成部分之一。我将解释我对维基百科中递归关系概念的理解。

通常k 用于多集基数(您的问题称为n),而n 用作要选择的集合的基数(不是多集)来自(您问题中的max)。

对于f(n, k),基本情况是:

f(n, 0) = 1
one way to fill the empty multiset

还有,

f(0, k) = 0
no ways to choose from an empty set

对于常规情况,我们考虑nth 元素(来自选择集)。我们想计算所有包含它的组合以及所有缺少它的组合。计算没有nth 元素的所有组合很容易:我们将相同的多集计数功能应用于k,但选择更少:

f(n - 1, k)

现在要计算至少包含一个nth 元素的组合,我们设想从n 项目中选择所有方法(其中一些不包含nth 元素)但保存一个位置在每个组合中,我们将放置一个 nth 元素,所以我们最终得到:

f(n, k - 1)

把它们放在一起:

function f(n, k){
  if (n == 0)
    return 0;
  if (k == 0)
    return 1;

  return f(n - 1, k) + f(n, k - 1);
}

console.log(f(2, 3));
console.log(f(3, 2));

【讨论】:

    【解决方案2】:

    递归可能一开始很难理解,但是一旦你了解它就会很清楚。缺点是递归比基本的 for 循环 (Space complexity of recursive function) 需要更多的空间。对于某些问题,首先编写递归版本然后将其编写为 for-loop 会更容易。此外,如果空间不是问题,它有助于使您的代码干净(没有 for 循环!)

    我做了一些基本的递归,至少为你写下的两个例子给出了正确的答案。我可能错过了一个边缘案例:编写每个函数调用和一些(前卫的)测试用例可能是一个好习惯。

    public int recursiveWrapper(int n, int max) {
        return recursive(n, max, 1, 1);
    }
    
    public int recursive(int n, int max, int lower, int current) {
    //        // for your convenience
    //        System.out.println("n:" + n + " max:" + max + " lowerbound:" + lower + " current:" + current);
    
        // Base case
        if (n <= 1 && lower == max) {
            return 1;
        }
    
        // Recursive step
        // Sequence complete, move to next column
        if (current == max) {
            // Make sure the lower bound does not go beyond the max. number
            int updatedLower = (lower + 1 > max) ?  lower : lower + 1;
    
            return 1 + recursive(n - 1, max, updatedLower, updatedLower);
        }
    
        return 1 + recursive(n, max, lower, current + 1);
    }
    

    简而言之: 在第二个例子中:

    n=2 最大值=3

    {1,1}
    {1,2}
    {1,3}
    {2,2}
    {2,3}
    {3,3}
    

    注意由于从左到右的数字必须相等或更大的规则而出现的数字模式: 第二列:1>2>3>2>3>3 第一列:1>1>1>2>2>3

    递归中的“下界”参数基本上是新“序列”可以采用的最低可能数字(其中每个序列为lower bound -&gt; max number)。然后,基本情况是下限等于上限并且每列都完成了所有“序列”。可能不是一个非常清晰的解释 - 当您看到我复制粘贴的代码中的注释行打印出的内容时,它可能会有所帮助。

    注意:也许可以用更少的参数进行递归。确保阅读大量有关递归的内容(例如wikipedia 或您的学习书?)。递归可以更轻松地找到解决方案并理解复杂和抽象的问题。

    【讨论】:

      【解决方案3】:

      由于时间原因,我写了一些效率较低的代码,试试看,它会给你目录,我希望,

      package com.exercise;
      
      import java.util.Arrays;
      
      public class Permutation {
      
      public static void permutation(String str) {
          permutation("", str);
      }
      
      private static void permutation(String prefix, String str) {
          int n = str.length();
          if (n == 0)
              System.out.println(prefix);
          else {
              for (int i = 0; i < n; i++)
                  permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n));
          }
      }
      
      private static void permutationOnInt(String prefix, String str, int max) {
      
          int n = str.length();
      
          if (n == 0)
              System.out.println(prefix);
          else {
              for (int i = 0; i <= n; i++)
                  permutation(prefix + str.charAt(i), str.substring(0, i) + str.substring(i + 1, n));
          }
      }
      
      public static int[] return_Array(int length) {
          int[] a = new int[length];
          for (int i = 0; i < length; i++) {
              a[i] = i + 1;
          }
          return a;
      
      }
      
      public static void main(String[] args) {
          String fn = Arrays.toString(return_Array(3));
          String apple = String.join(",", fn.replace("[", "").replace("]", "").replace(",", "").replaceAll("\\s+", ""));
          permutationOnInt("", apple, 3);
      }
      }
      

      得到结果后,您可以将其转换回数组。 重要:此代码完全没有优化。我稍后会发布优化

      【讨论】:

        猜你喜欢
        • 2015-02-09
        • 2021-07-29
        • 1970-01-01
        • 1970-01-01
        • 2012-11-05
        • 1970-01-01
        • 2020-07-28
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多