问题:
一个台阶总共有n级,如果一次可以跳1级,也可以跳2级。
求总共有多少总跳法,并分析算法的时间复杂度。
这道题最近经常出现,包括MicroStrategy等比较重视算法的公司
都曾先后选用过个这道题作为面试题或者笔试题。
分析:
这是典型的递归问题。以f(n)表示共有的跳法,可以先跳一级或是先跳2级,则问题转换为需要求解f(n-1)和f(n-2)。
当n=1是只有一种跳;当n=2时有两种跳法;当n>=3时有,f(n) = f(n-1)+f(n-2)。其递归算法为:
NSUInteger recursionJumpNum(NSUInteger steps){
if (steps == 1) {
return 1;
}
if (steps == 2) {
return 2;
}
return recursion_StepsNum(steps-1) + recursion_StepsNum(steps – 2);
}
时间复杂度分析:
问题可表示为 f(n+1) = f(n) + f(n-1), n>= 2, f(1) = 1, f(2) = 2
设
有
==>
设 则
又
==>
==>
非递归算法:
尾递归形式
NSUInteger recursionJumpNum (NSUInteger steps){
NSUInteger count = 0;
if (steps == 1) {
count = 1;
}else if (steps == 2) {
count = 2;
}else if (steps > 2) {
NSUInteger num1 = nonrecursionJumpNum(steps – 1);
NSUInteger num2 = nonrecursionJumpNum(steps – 2);
count = num1 + num2;
}
return count;
}
非递归形式
NSUInteger nonrecursionJumpNum(const NSUInteger steps){
NSUInteger index = 1;
NSUInteger count = 0;
NSUInteger count_minus_one = 0;
NSUInteger count_minus_two = 0;
while (index <= steps) {
if (index == 1) {
count = 1;
}else if (index == 2) {
count_minus_one = count;
count = 2;
}else if (index > 2) {
count_minus_two = count_minus_one;
count_minus_one = count;
count = count_minus_one + count_minus_two;
}
index++;
}
return count;
}
非递归优化
NSUInteger nonrecursionJumpNum(const NSUInteger steps){
NSUInteger index = 1;
NSUInteger count = 0;
NSUInteger count_minus_one = 0;
NSUInteger count_minus_two = 0;
while (index <= steps) {
if (index > 2) {
count_minus_two = count_minus_one;
count_minus_one = count;
count = count_minus_one + count_minus_two;
}else if (index == 1) {
count = 1;
}else if (index == 2) {
count_minus_one = count;
count = 2;
}
index++;
}
return count;
}
代码 https://github.com/wangjufan/algorithm_Recursion/tree/master