【发布时间】:2015-10-22 23:28:19
【问题描述】:
有人要求我构建一个涉及排列的算法,但我有点难过,正在寻找一个起点。详细是这里...
你正在爬 n 个楼梯。每次您可以一次攀爬 1 或 2 级台阶。您可以通过多少种不同的方式登顶?
有什么建议可以解决这个挑战吗?
【问题讨论】:
-
为什么要投赞成票?这显然是一个没有任何研究努力的问题,而且对于 SO 来说太宽泛了。
标签: algorithm permutation
有人要求我构建一个涉及排列的算法,但我有点难过,正在寻找一个起点。详细是这里...
你正在爬 n 个楼梯。每次您可以一次攀爬 1 或 2 级台阶。您可以通过多少种不同的方式登顶?
有什么建议可以解决这个挑战吗?
【问题讨论】:
标签: algorithm permutation
你错了排列。排列涉及集合的排序。这个问题是另外一回事。
涉及产生相同问题的另一个实例的简单决策的问题通常可以通过动态规划来解决。这是这样一个问题。
当你有 n 步要爬时,你可以选择 1 步或 2 步的跳跃,然后分别解决 n-1 和 n-2 步的较小问题。在这种情况下,您想要添加可能性的数量。 (很多 DP 会寻找最小值或最大值,所以这有点不寻常。)
“基本情况”是指您有 0 步或 1 步。恰好有一种方法可以遍历其中的每一个。
考虑到所有这些,我们可以将爬升 n 步的方法数编写为递归表达式:
W(n) = W(n - 1) + W(n - 2) if n > 1
1 n == 0, 1
现在您不想将其实现为简单的递归函数。由于每次调用 W 都会调用自身两次,因此计算需要 n 的指数时间。然而,这些电话中的大多数都是不必要的重复。怎么办?
完成工作的一种方法是找到一种按顺序计算 W(i) 值的方法。对于 1 值 DP,它通常很简单,所以在这里:
W(0) = 1
W(1) = 1 (from the base case)
W(2) = W(1) + W(0) = 1 + 1 = 2
W(3) = W(2) + W(1) = 2 + 1 = 3
你明白了。这确实是一个非常简单的DP。为了计算 W(i),我们只需要两个先前的值,W(i-1) 和 W(i-2)。一个简单的 O(n) 循环就可以解决问题。
作为健全性检查,请查看 W(3)=3。确实,要上 3 步,我们可以先跳 1 后 2、2 后 1 或 3 跳 1。这是 3 种方式!
不能再抗拒一个? W(4)=2+3=5。跳跃序列是(2,2),(2,1,1),(1,2,1),(1,1,2)和(1,1,1,1):5种方式。
事实上,上面的图表很多人都会觉得很熟悉。爬 n 步的方法数是第 (n+1) 个斐波那契数。您应该自己编写循环代码。如果卡住了,您可以查找已发布的数百个示例中的任何一个。
【讨论】:
private static void printPath(int n,String path) {
if (n == 0) {
System.out.println(path.substring(1));
}
if (n-1 >=0) {
printPath(n-1,path + ",1");
}
if (n-2 >=0) {
printPath(n-2,path + ",2");
}
}
public static void main(String[] args) {
printPath(4,"");
}
【讨论】:
因为它看起来像一个编程作业,所以我会给你一些开始的步骤,而不是给出实际的代码:
1 和2 来调用函数
【讨论】: