【问题标题】:Recursive function that returns the number of possible combinations返回可能组合数的递归函数
【发布时间】:2018-01-11 04:18:33
【问题描述】:

我参加了一次面试,并被问到一个我想了解解决方案的问题。

问题

创建一个递归函数,该函数返回给定长度的数组的可能组合数,该数组可以由非重复连续整数数组组成。

f(array, length) = 组合

示例 1

  • 数组 = [0,1,2,3]
  • 长度 = 2
  • 组合 = 10(所有组合:[0,0] [0,1] [0,2] [0,3] [1,1] [1,2] [1,3] [2,2] [2,3] [3,3])
  • 请注意,[0,0] 是允许的,但 [1,0] 不允许,因为 [0,1] 已定义

示例 2

  • 数组 = [0,1]
  • 长度 = 3
  • 组合 = 4(所有组合:[0,0,0] [0,0,1] [0,1,1] [1,1,1])

提供了一个“提示”。面试官说阵列本身不重要;长度就足够了。

【问题讨论】:

  • 您不了解问题或解决方案吗?你知道递归是如何工作的吗?像这样的问题不是要得到“正确的答案”,而是要考虑如何解决问题。如果您不了解递归,那么该解决方案对您也没有意义。
  • @DStanley - 我确实理解递归,尽管它增加了复杂性。我最难理解的是如何使用递归来完成所需的结果。我的直觉是使用一系列非常丑陋的循环。它完全把我难住了。
  • 您的问题中没有任何内容可以解释为什么 [2,1] 和 [1,0,0] 不是有效的组合。
  • @MattTimmermans 如果 [1,0] 是不允许的,因为 [0,1] 已定义,那么我猜 [2,1] 不是因为 [1,2] 已定义,与 [ 1,0,0] 和 [0,1,0] 定义为 [0,0,1]。
  • 也没什么好说的,为什么 [0,2] 不是解决方案,因为“非连续”的标准仅适用于输入数组

标签: arrays math recursion


【解决方案1】:

该算法可以递归表示,因为解决方案可以用较小输入的解决方案来表示。这里的“小”有两层含义:

  • 数组的一个子集;特别是当前元素索引之后的子数组

  • 较小长度的解决方案;这些可以加在一起得到长度+ 1的解决方案

停止条件:

  • 当数组大小A = 1时-只能生成一种组合

  • 当长度L = 1-组合数=数组元素数时

完全递归的过程是一个非常简单的单行:

return [recursive call to rest of array, same length] + 
       [recursive call to same array, length - 1]

这称为动态规划

代码:

int F(int A, int L)
{
    if (A <= 1) return 1;
    if (L <= 1) return A;
    return F(A - 1, L) + F(A, L - 1);
}

测试:

  • F(4, 2) = 10
  • F(2, 3) = 4
  • F(3, 5) = 21(用纸笔描一下,自己看看)

编辑:我给出了一个优雅而简单的解决方案,但我可能没有像@RoryDaulton 那样解释它。考虑也给予他的回答。

【讨论】:

  • 非常感谢!这是有道理的,但即使看到它被写出来,我也几乎无法理解它。深入研究这些东西会很有趣。吹手机屏幕却没有解释问题让我很生气。
【解决方案2】:

您没有提供目标语言,也没有说您需要多少帮助。因此,如果您知道某种语言的递归,我将给出一个应该易于编码的算法的总体概念。询问您是否需要更多 Python 代码,这是我目前的首选语言。

您知道您需要进行递归,并且您有两件事可以递归:给定数组的长度或所需数组的长度。让我们递归第二个,假设给定的数组是[0, 1, ..., n-1],因为你知道实际的内容是不相关的。

如果所需的长度r1,您知道只有n 所需的数组,即[0][1]、...、[n-1]。所以有你的递归的基本情况。

如果您有一个长度为r-1 的“组合”,如何将其扩展为长度r 并保持要求?查看长度为r-1 的数组中的最后一个元素——我们称之为k。下一个元素不能小于该值,因此所有可能扩展到长度r 的数组都是r-1 数组加上k', 'k+1,...,n-1。这些是 n-k 长度为 r 的数组。

是否清楚如何编码?请注意,您不需要保留所有长度为r-1 的数组,您只需要计算以元素01 或...n-1 结尾的数组的数量。这使得编码很方便——不需要太多的内存。事实上,事情还可以进一步减少——我将把它留给你。

请注意,面试官可能不想要代码,他希望你的思维过程导致代码看到你的思维方式。这是思考问题的一种方式。

【讨论】:

  • 谢谢罗里,这很有帮助。感谢您花时间分解思考过程。
猜你喜欢
  • 2015-10-23
  • 2015-04-27
  • 2021-08-14
  • 2019-04-25
  • 2021-04-06
  • 2022-01-16
  • 1970-01-01
相关资源
最近更新 更多