你需要爬上一个有n个台阶的楼梯,你决定跳上台阶进行一些额外的锻炼。您可以在一次跳跃中覆盖最多k个步骤。返回你可以采取的所有可能的跳跃序列,以爬上楼梯,整理好。
我的实施显然给了我错误的答案。
def climbingStaircase(n, k):
final_res=[]
final_res.append(CSR(n,k,[]))
return final_res
def CSR(n,k,res):
if n == 0:
return res
else:
for i in range(1,k+1):
if n-i>=0:
res.append(i)
n=n-i
res=CSR(n,i,res)
return res
对于n = 4且k = 2,输出应为
[[1, 1, 1, 1],
[1, 1, 2],
[1, 2, 1],
[2, 1, 1],
[2, 2]]
实际输出:
[[1,1,1,1,2,1]]
有人可以指出我缺少哪一部分吗?
答案 0 :(得分:3)
下面的代码中存在一个很大的问题:您在步骤范围内扣除每种可能性的步数。
n=n-i
res=CSR(n,i,res)
如果你已经完成了一步跳跃的探索,你需要回溯并尝试从相同的起点(此实例& #39;原始值n
),跳跃为2步。将代码更改为:
res = CSR(n-i, i, res)
这样可以在循环过程中保持n
值不变。
此外,您不能将未来的跳跃限制为您刚拍摄的最大值。也改变第二个参数:
res = CSR(n-i, k, res)
这应该让你感动。也可以尝试这个可爱的debug博客寻求帮助。至少插入一个或两个跟踪语句,例如
print n, k, res
在你的日常工作中。
<强> CAVEAT 强>
这不是你的全部麻烦。剩下的最大问题是CSR
只返回一个解决方案:您执行的每个步骤都会附加到相同的列表中。您需要一种方法将已完成的解决方案收集为单独的列表;在append
完全完成后,climbingStaircase
中的CSR
只执行一次。
您需要在n==0
识别已完成的解决方案。
调试帮助
以下是程序的一个版本,其中修复了递归参数,并插入了调试跟踪。
indent = ""
def climbingStaircase(n, k):
final_res = []
final_res.append(CSR(n, k, []))
return final_res
def CSR(n, k, res):
global indent
indent += " "
print indent, n, k, res
if n == 0:
print "SOLUTION", res
else:
for i in range(1, k+1):
if n-i >= 0:
CSR(n-i, k, res + [i])
indent = indent[:-2]
print climbingStaircase(4, 2)
注意使用&#34;缩进&#34;帮助可视化您的递归和回溯。这里的关键部分是,我没有全局更新res
,而是将其留作局部变量。我现在还删除了返回值,只需转储就可以输出解决方案。你可以看到它是如何工作的:
4 2 []
3 2 [1]
2 2 [1, 1]
1 2 [1, 1, 1]
0 2 [1, 1, 1, 1]
SOLUTION [1, 1, 1, 1]
0 2 [1, 1, 2]
SOLUTION [1, 1, 2]
1 2 [1, 2]
0 2 [1, 2, 1]
SOLUTION [1, 2, 1]
2 2 [2]
1 2 [2, 1]
0 2 [2, 1, 1]
SOLUTION [2, 1, 1]
0 2 [2, 2]
SOLUTION [2, 2]
[None]
有了这些东西,我很有希望你可以追踪你的逻辑,并找出如何在你选择的水平上捕捉解决方案的顺序。
答案 1 :(得分:2)
成功实施了Prune的答案。
def climbingStaircase(n, k):
res=[]
CSR(n,k,[],res)
return res
def CSR(n,k,str_, res):
if n == 0:
res.append(str_)
else:
for i in range(1,k+1):
if n-i>=0:
CSR(n-i,k,str_+[i],res)
答案 2 :(得分:0)
此解决方案的快速Java版本:
int[][] climbingStaircase(int n, int k) {
List<ArrayList<Integer>> list = new ArrayList<>();
climb(n, k, new ArrayList<Integer>(), list);
// convert to int[][]
int[][] result = new int[list.size()][];
for (int i=0; i<list.size(); i++) {
List<Integer> l = list.get(i);
int [] arr = new int[l.size()];
for (int j=0; j<l.size(); j++)
arr[j] = l.get(j);
result[i] = arr;
}
return result;
}
void climb(int n, int k, ArrayList<Integer> prev, List<ArrayList<Integer>> list) {
if (n==0) { // no more stairs, done climbing
list.add(prev);
} else {
for (int i=1; i<=k; i++) { // climb remaining stairs in intervals from 1 to k steps
if (i <= n) { // no need to test intervals larger than remaining # of stairs
ArrayList<Integer> branch = new ArrayList<>(prev);
branch.add(i);
climb(n-i, k, branch, list);
}
}
}
}