接上一篇递归算法博客,讲一下常见的一个爬楼梯问题:
1.常见的一个简单写的爬楼梯问题为:一人要爬n个台阶,一步能爬1个台阶或者2个台阶,问:爬完n个台阶一共有多少种爬法?
解析:这个人开始爬台阶时只可能有两种爬法:
1):爬1个台阶,剩下的n-1个有f(n-1)种爬法;
2):爬2个台阶,剩下的n-2个有f(n-2)中爬法;
除了这两种爬法,没有其他的了,所以很明显f(n) = f(n-1) + f(n-2) 。很明显这是一个递归类问题。
需要注意的是f(2) = f(1) + f(0), 很显然f(1)=1,f(2)=2,所以f(0) = 1,所以函数如下:
func getMethodCount(allsteps: UInt) -> UInt{
if allsteps == 0{
return 1
} else if allsteps == 1{
return 1
} else if allsteps == 2{
return 2
} else {
return getMethodCount(allsteps - 1) + getMethodCount(allsteps - 2)
}
}
2.稍微增加难度的一个问题:一个人要爬n个台阶,一步最多能爬m个台阶,问:爬完n个台阶一共有多少种爬法?
解析:
一次最多爬1阶 m=1
m=1 f(1) = f(1-1)
一次最多爬2阶 m=2
m=2 f(2) = f(2-1) + f(2-2)
一次最多爬3阶 m=3,开始会有三种方式:爬1阶,爬2阶,爬3阶。那么爬1阶,剩下的f(n-1);爬2阶,剩下的f(n-2);爬3阶,剩下的f(n-3)
所以总的爬法:f(n) = f(n-1) + f(n-2) + f(n-3)
一次最多爬m阶,开始会有m种方式:爬1阶,爬2阶。。。爬n阶。那么爬1阶,剩下的f(n-1).....爬m阶,剩下的为f(n-m)
所以 f(n) = f(n-1) + f(n-2) + ... +f(n-m)
所以n个台阶为f(n-1) + f(n-2) + ...+ f(n-m)
所以只需要按照递归思想,考虑n和m的大小问题即可,函数如下:
func getMethodCount1(#allSteps: UInt, maxStep: UInt) -> UInt{
var sumStep: UInt = 0
if (allSteps == 0){
return 1
}
if allSteps == 1{
return 1
} else if allSteps >= maxStep {
//如果allSteps大于每步最大台阶数,则设置第一步为maxStep之内的一个台阶数,然后递归循环
for var i: UInt = 1; i <= maxStep; i++ {
sumStep += getMethodCount1(allSteps: allSteps - i, maxStep: maxStep)
}
} else {
//如果allSteps小于maxStep,则将一步最大台阶数缩小为allSteps,重新递归
for var i:UInt = 1; i <=allStep; i++ {
<span style="white-space:pre"> </span>sumStep += getMethodCount1(allSteps: allSteps - i, maxStep: allSteps)
<span style="white-space:pre"> </span> }
}
return sumStep
}