求总共有多少总跳法,并分析算法的时间复杂度。
分析:在九月腾讯,创新工场,淘宝等公司最新面试十三题中第23题又出现了这个问题,题目描述如下:23、人人笔试1:一个人上台阶可以一次上1个,2个,或者3个,问这个人上n层的台阶,总共有几种走法?咱们先撇开这个人人笔试的问题(其实差别就在于人人笔试题中多了一次可以跳三级的情况而已),先来看这个第27题。
首先考虑最简单的情况。如果只有1级台阶,那显然只有一种跳法。如果有2级台阶,那就有两种跳的方法了:一种是分两次跳,每次跳1级;另外一种就是一次跳2级。
现在我们再来讨论一般情况。我们把n级台阶时的跳法看成是n的函数,记为f(n)。当n>2时,第一次跳的时候就有两种不同的选择:一是第一次只跳1级,此时跳法数目等于后面剩下的n-1级台阶的跳法数目,即为f(n-1);另外一种选择是第一次跳2级,此时跳法数目等于后面剩下的n-2级台阶的跳法数目,即为f(n-2)。因此n级台阶时的不同跳法的总数f(n)=f(n-1)+(f-2)。
我们把上面的分析用一个公式总结如下:
/ 1 n=1
f(n)= 2 n=2
\ f(n-1)+(f-2) n>2
那么,如果是人人笔试那道题呢?一个人上台阶可以一次上1个,2个,或者3个,岂不是可以轻而易举的写下如下公式:
/ 1 n=1
f(n)= 2 n=2
4 n=3 //111, 12, 21, 3
\ f(n-1)+(f-2)+f(n-3) n>3
简单的一种算法如下:
long Fibonacci_Solution1(unsigned int n)
{
int result[4] = {0,1,2,4};
if(n <=3)
return result[n];
return Fibonacci_Solution1(n - 1) + Fibonacci_Solution1(n - 2)+Fibonacci_Solution1(n - 3);
}
原来上述问题就是我们平常所熟知的Fibonacci数列问题。可编写代码,如下:
含有递归的版本和迭代的版本:
long long jump_sum2(int n) //迭代(经测试代码是对的)
{
//assert(n>0);//如果表达式的值为假,整个程序将退出,并输出一条错误信息。如果表达式的值为真则继续执行后面的语句。
if (n == 1 || n == 2) return n;
long long an, an_2=2, an_1=1;
for (; n>=3; n--)
{
an = an_2 + an_1;
an_1 = an_2;
an_2 = an;
}
return an;
}
int _tmain(int argc, _TCHAR* argv[])
{
//cout<<Fibonacci_Solution2(5)<<endl;
//cout<<jump(100)<<endl;
//cout<<jump_sum(5)<<endl;
cout<<jump_sum2(100)<<endl;
system("pause");
return 0;
}
1594

被折叠的 条评论
为什么被折叠?



