【问题标题】:Recursion Problem - given array n and a number k递归问题 - 给定数组 n 和一个数字 k
【发布时间】:2019-04-15 08:11:07
【问题描述】:

给定一个数组大小 n 和一个正数 max(max 表示我们可以用来放置在数组中的数字的范围)。

我想计算可以在数组中放置多少个已排序数字的组合。

例如:

如果n = 3, max = 2.(我们可以使用的唯一数字是 1/2,因为最大值是 2)所以排序数组有 4 种组合

 1. {1,1,1}
 2. {1,1,2}
 3. {1,2,2}
 4. {2,2,2}

我编写了一些代码并成功通过了这个特定的示例,但是max > 2 没有返回正确答案的任何其他示例。

我发现的问题是,当递归到达最后一个索引时,它不会尝试第三个数字,而是折回。

我的代码:

private static int howManySorted(int n, int max, int index, int numToMax, int prevNum) {        
    // If the value is bigger then max return 0
    if(numToMax > max) {
        return 0;
    }
    if (numToMax < prevNum) {
        return 0;
    }
    //If Index reached the end of the array return 1
    if(index == n) {
        return 1;
    }

    int sortTwo =  howManySorted(n, max, index+1, numToMax, numToMax);
    int sortOne =  howManySorted(n, max, index+1, numToMax+1, numToMax);
    return ((sortOne+sortTwo));
}

public static int howManySorted(int n, int max) {
    return howManySorted(n, max, 0, 1, 0);
}

【问题讨论】:

  • 好奇:numToMax &lt; prevNum 什么时候会是真的?
  • 你在代码中只能递归两次,即下一个数只能和前一个相同或高一个,这意味着对于max &gt; 2你不会找到1,1,5这样的解决方案,因为这是 4 的跳跃。
  • 是的,我知道这就是我在此处发帖的原因(:
  • 仅供参考: 参数index 是多余的。在递归调用中,不要将index0 计数到n,而是将n 倒数到0
  • 所以在递归调用周围添加一个循环,从numToMax循环到max。 --- 另外,鉴于我的第一条评论,参数prevNum 是多余的。摆脱它。

标签: java sorting recursion


【解决方案1】:

以“{1”开头,并在每次递归时添加元素“{1,1”和/或值“{2”。当它达到 n 个元素数组时,我们将其添加到计数器中。 n 是数组中的元素数 max 是每个元素的最大值。 minimum 是 1。 element 是正在操作的数组中的当前单元格。我们从 1 开始(在实际数组中表示 0)。 value 是当前元素的当前值。我们从 1 开始。

// external function according to the given question
public static int count (int n, int max) 
{
    return count(n,max, 1, 1);
}

private static int count (int n, int max, int element, int value) 
{
    int counter = 0;
    // only if our array reached n elements we count the comination
    if (element == n) 
        counter++;
    else // we need to continue to the next element with the same value
        counter += count(n, max, element +1, value);
    if (value < max) // if our current element didn't reach max value
        counter += count (n, max, element, value+1); 
    return counter;
}

【讨论】:

    【解决方案2】:

    我认为您需要更改您的两个递归调用(这就是它只达到值 2 的原因)并执行与您的 max 参数一样多的调用:

    private static int howManySorted(int n, int max, int index, int numToMax, int prevNum) {
        // If the value is bigger then max return 0
        if (numToMax > max) {
            return 0;
        }
        if (numToMax < prevNum) {
            return 0;
        }
        //If Index reached the end of the array return 1
        if (index == n) {
            return 1;
        }
    
        int result = 0;
        for (int i = 0; i < max; i++)
            result += howManySorted(n, max, index + 1, numToMax + i, numToMax);
    
        return result;
    }
    

    【讨论】:

      【解决方案3】:

      我相信您可以简化对此类问题的回答

      private static long howManySorted(int length, int min, int max) {
          if (length == 1) {
              return max - min + 1;
          }
      
          // if (min == max) {
          //    return 1;
          // }
      
          long result = 0;
          for (int i = min; i <= max; i++) {
              result += howManySorted(length - 1, i, max);
          }
          return result;
      }
      
      public static long howManySorted(int length, int max) {
          if ((length < 1) || (max < 1)) {
              throw new IllegalArgumentException();
          }
      
          return howManySorted(length, 1, max);
      }
      

      客户端应该调用public方法。

      所以你可以看到终止条件是当剩余的length 为 1,或者min 达到max。即使删除第二个终止条件也不会改变结果,但可以提高性能和递归次数。

      【讨论】:

        【解决方案4】:

        只需测试我的代码,我认为它可以解决您的问题:

        class Test {
        private static int howManySorted(int n, int max) {
            //Better time complexity if u use dynamic programming rather than recursion.
        
            if (n == 0) return 1;
        
            int res = 0; // "res" can be a very large.
        
            for (int i = n; i >= 1; i--) {
                for (int j = max; j >= 1;j--) {
                    res += howManySorted(i-1, j-1);
                }
            }
        
            return res;
        }
        
        public static void main(String[] args) {
            System.out.println(howManySorted(3, 2));
        }
        

        }

        如果你使用动态编程,这段代码会运行得更快,并且注意答案,它可能是一个非常大的整数。

        【讨论】:

          【解决方案5】:

          你们忘记了他需要一个只使用递归的解决方案。 可能是 CS 类的 Java 作业。

          我也有这个问题。

          这是我想出的答案:

          /**
           * @param n Number of values in the array
           * @param max Maximum value of each cell in the array
           * @return int
           */
          public static int howManySorted(int n, int max) {
              return howManySorted(max, max, 1, n - 1);
          }
          
          /**
           *
           * @param value The current value
           * @param max The maximum possible value (not allowed to use global parameters, so the parameter value always stays the same)
           * @param min The minimum value allowed in this index. Determined by the value of the previous index (when first called, use value 1)
           * @param index The index of the value being manipulated
           * @return
           */
          public static int howManySorted(int value, int max, int min, int index) {
              //If any of these cases are found true, it means this value is invalid, don't count it
              if (index < 0 || value < min) {
                  return 0;
              }
              //First lower the value in the same index, the result is the number of valid values from that branch
              int lowerValue = howManySorted(value - 1, max, min, index);
              //Now check all the valid values from the next index - value is max-1 to prevent counting twice some numbers
              int lowerIndex = howManySorted(max - 1, max, value, index - 1);
              //Return 1 (this number we are at right now) + all of its children
              return 1 + lowerValue + lowerIndex;
          }
          

          【讨论】:

            【解决方案6】:

            我将每个系列(例如'1,1,2')视为一个数组,所以一开始我写了这样的东西:

            public static void main(String[] args)
            {
                System.out.println(howManySorted(3, 2, 1, "")); // 4
                System.out.println(howManySorted(2, 3, 1, "")); // 6
            }
            private static int howManySorted(int n, int max, int index, String builder)
            {
                if (max == 0) // if we exceeds max, return 0.
                    return 0;
            
                if (n == 0) // num represents how many individual numbers we can have, if it is zero it means we have the required length (e.g. if n = 3, we have 'x1,x2,x3').
                {
                    System.out.println(builder.substring(0, builder.length() - 2));
                    return 1;
                }
            
                int r1 = howManySorted(n - 1, max, index, builder + index + ", "); // i added additional var 'index' to represent each number in the list: (1,1,1)
                int r2 = howManySorted(n, max - 1, index + 1, builder); // I'm increasing the index and decreasing the max (1,1,**2**)
            
                return r1 + r2;
            }
            

            但最终,我们不需要“索引”或“构建器”,它们只是为了强调我是如何解决它的......

            public static void main(String[] args)
            {
                int max = 2, n = 3;
                System.out.println(howManySorted(n, max)); // 4
            
                int max1 = 3, n1 = 2;
                System.out.println(howManySorted(n1, max1)); // 6
            }
            
            public static int howManySorted(int n, int max)
            {
                if (max == 0) // if we exceeds max, return 0.
                    return 0;
            
                if (n == 0) // like we said, num represents how many individual numbers we can have, if it is zero it means we have the required length (e.g. if n = 3, we have 'x1,x2,x3').
                    return 1;
            
                int r1 = howManySorted(n - 1, max);
                int r2 = howManySorted(n, max - 1);
            
                return r1 + r2;
            }
            

            【讨论】:

            • 请补充说明
            • 我添加了,希望对你有帮助?,请尝试调试
            猜你喜欢
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 1970-01-01
            • 2019-09-19
            • 2023-03-11
            • 2022-01-07
            相关资源
            最近更新 更多