第一次实习面试-fabonaci数列
来源:互联网 发布:淘宝里范冰冰的公益 编辑:程序博客网 时间:2024/05/20 01:36
毕业前去卓越亚马逊参加暑期实习的面试,本来是3点开始,结果我2点半就到了,进去之后发现这种企业的写字楼是真NB,不论是从硬件设置还是公司气氛,一看就是NB公司。随后面试开始,一面是算法+数据结构,二面是设计模式+面向对象设计。至于这其中的具体细节我就不说了,网上的面经很多。
说起这个数列,学过数学的人都知道,就是f(n)=f(n-1)+f(n-2),其中f(1)=f(0)=1;一般要输出f(k),使用递归就可以实现,递推的式子已经很明显,但是问题就怕深究,如果仅仅是满足于此,结果只能被面试官完虐。后来在网上找资料,才发现至少有5种方式来实现。具体参见http://www.cnblogs.com/CCBB/archive/2009/04/25/1443441.html
1.最直观的思路和写法---递归
int fibonacci(int n)
{
if(n==0 || n==1)
return 1;
else
return fibonacci(n-1)+fibonacci(n-2);
}
这个程序因为在计算f(n)的时候,需要得到从f(2)到f(n-1),而计算f(n-1)时又重复计算了f(n-2),效率比较低,时间复杂度是o(n^2)
2.另一种递归
这是在大_智_慧的博客上看到的,不同于以往的递归写法
long fib(int n,long a,long b,int count)
{
if(count==n)
return b;
return fib(n,b,a+b,++count);
}
int main()
{
fib(n,0,1,1);
}
这种方法其实是迭代方法的一种递归表现形式,显然a和b的初始值是0和1,而后b作为a的新值,而a+b作为b的新值,同时count加1,直到最底层,参考博客只是说这种方法可以得到近似线性的复杂度。
3.迭代法
long fib(int n)
{
if(n<0)
return -1;
int a=1;b=1;
for(int i=1;i<n;i++)
{
b=a+b;
a=b-a;
}
return b;
}
这个程序显然实现了在o(n)的复杂度情况下输出f(n)(话说面试的时候我没有想出来,以前还见过这个程序,现在看是真TMD简单,估计面试官相当鄙视我)
4.通项公式
听上去有点高中数学的味道,但是不失为一种方法,而且理论上还是巨NB,为什么这么说?
使用考研时用的什么二阶差分方程解法(具体我已经忘了,好像是特征方程吧),解得它的解为
x1=(1+sqrt(5))/2,x2=(1-sqrt(5))/2,这样就得到:f(n)=(x1^n-x2^n)/sqrt(5)
时间复杂度为o(1),但是这仅仅是在理论上,因为会涉及到在计算方根时精度的损失问题,再就是开方和乘法的效率对执行时间的影响。
代码如下:
long fib(int n)
{
double m=sqrt(5);
doubie x=(1+m)/2;
double y=(1-m)/2;
return (pow(x,n)-pow(y,n))/m;
}
5.使用矩阵相乘
从通项公式可得到矩阵形式为:
f(n) 1 1 f(n-1)
f(n-1) = 1 0 * f(n-2)
依次展开,直到f(1)=f(0)=1
f(n) 1 1
f(n-1) = 1 0 ^ (n-1)
这样,问题就转化为求一个二阶01矩阵的n-1次方(百度空间不太给力,表示形式欠佳),使用二分的方法实现,比如次方数是13,映射为2进制即1101.则矩阵A的13次=A^8*A^4*A1;
以下代码转自开头提到的博客,写的非常好:
class Matrix
{
public:
long matr[2][2];
Matrix(const Matrix&rhs);
Matrix(long a, long b, long c, long d);
Matrix& operator=(const Matrix&);
friend Matrix operator*(const Matrix& lhs, const Matrix& rhs)
{
Matrix ret(0,0,0,0);
ret.matr[0][0] = lhs.matr[0][0]*rhs.matr[0][0] + lhs.matr[0][1]*rhs.matr[1][0];
ret.matr[0][1] = lhs.matr[0][0]*rhs.matr[0][1] + lhs.matr[0][1]*rhs.matr[1][1];
ret.matr[1][0] = lhs.matr[1][0]*rhs.matr[0][0] + lhs.matr[1][1]*rhs.matr[1][0];
ret.matr[1][1] = lhs.matr[1][0]*rhs.matr[0][1] + lhs.matr[1][1]*rhs.matr[1][1];
return ret;
}
};
Matrix::Matrix(long a, long b, long c, long d)
{
this->matr[0][0] = a;
this->matr[0][1] = b;
this->matr[1][0] = c;
this->matr[1][1] = d;
}
Matrix::Matrix(const Matrix &rhs)
{
this->matr[0][0] = rhs.matr[0][0];
this->matr[0][1] = rhs.matr[0][1];
this->matr[1][0] = rhs.matr[1][0];
this->matr[1][1] = rhs.matr[1][1];
}
Matrix& Matrix::operator =(const Matrix &rhs)
{
this->matr[0][0] = rhs.matr[0][0];
this->matr[0][1] = rhs.matr[0][1];
this->matr[1][0] = rhs.matr[1][0];
this->matr[1][1] = rhs.matr[1][1];
return *this;
}
Matrix power(const Matrix& m, int n)
{
if (n == 1)
return m;
if (n%2 == 0)
return power(m*m, n/2);
else
return power(m*m, n/2) * m;
}
long fib4 (int n)
{
Matrix matrix0(1, 1, 1, 0);
matrix0 = power(matrix0, n-1);
return matrix0.matr[0][0];
}
上面的是C++代码,做到了很好的功能封装,如果用C的话可以考虑使用结构来定义这个矩阵,数据成员是矩阵的4个元素即可。
- 第一次实习面试-fabonaci数列
- 第一次实习面试
- 第一次实习面试
- 第一次IT实习面试
- 第一次实习面试总结
- 记第一次实习面试
- 第一次实习面试
- 第一次实习面试总结
- 第一次:实习面试
- 递归算法 解决fabonaci数列 C语言
- 记第一次实习面试经历
- 记第一次实习面试经历
- 第一次互联网实习面试经历
- 思科实习面试经验贴--第一次面试
- 2015-3-6 第一次实习电话面试
- 第一次实习面试经历--豆果美食
- 第一次实习
- 第一次实习面试感受----苦逼程序员生活初体验
- 编程宣言
- c++学习之利用tinyxml库进行对xml解析
- 老生长谈的JS预编译
- Postgresql数据库全文索引初试【对象关系型数据库管理系统】
- ORACLE:出错 ORA-12519, TNS:no appropriate service handler found
- 第一次实习面试-fabonaci数列
- 百度App应用创新大赛参赛作品:国民教育委员会
- 非阻塞通信
- 深入学习main()返回值问题
- 如何让cmd全屏显示?
- 线程同步
- asp.net常用函数表
- 家庭和睦、人生平淡也是一种成功
- Ubuntu下用minicom搭建TQ2440的程序下载dnw环境