斐波那契數列(1,1,2,3,5,8,...)
用函數表示為f(n)=f(n-1)+f(n-2) (n>2,f(1)=1,f(2)=1)
首先一般想到遞歸算法:
///
<summary>
/// Use recursive method to implement Fibonacci
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
static int Fn( int n)
{
if (n <= 0)
{
throw new ArgumentOutOfRangeException();
}
if (n == 1||n== 2)
{
return 1;
}
return checked(Fn(n - 1) + Fn(n - 2)); // when n>46 memory will overflow
}
/// Use recursive method to implement Fibonacci
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
static int Fn( int n)
{
if (n <= 0)
{
throw new ArgumentOutOfRangeException();
}
if (n == 1||n== 2)
{
return 1;
}
return checked(Fn(n - 1) + Fn(n - 2)); // when n>46 memory will overflow
}
遞歸算法時間復雜度是O(n2), 空間復雜度也很高的。當然不是最優的。
自然我們想到了非遞歸算法了。
一般的實現如下:
///
<summary>
/// Use three variables to implement Fibonacci
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
static int Fn1( int n)
{
if (n <= 0)
{
throw new ArgumentOutOfRangeException();
}
int a = 1;
int b = 1;
int c = 1;
for ( int i = 3; i <= n; i++)
{
c = checked(a + b); // when n>46 memory will overflow
a = b;
b = c;
}
return c;
}
/// Use three variables to implement Fibonacci
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
static int Fn1( int n)
{
if (n <= 0)
{
throw new ArgumentOutOfRangeException();
}
int a = 1;
int b = 1;
int c = 1;
for ( int i = 3; i <= n; i++)
{
c = checked(a + b); // when n>46 memory will overflow
a = b;
b = c;
}
return c;
}
這里算法復雜度為之前的1/n了,比較不錯哦。但是還有可以改進的地方,我們可以用兩個局部變量來完成,看下吧:
///
<summary>
/// Use less variables to implement Fibonacci
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
static int Fn2( int n)
{
if (n <= 0)
{
throw new ArgumentOutOfRangeException();
}
int a = 1;
int b = 1;
for ( int i = 3; i <= n; i++)
{
b = checked(a + b); // when n>46 memory will overflow
a = b - a;
}
return b;
}
/// Use less variables to implement Fibonacci
/// </summary>
/// <param name="n"></param>
/// <returns></returns>
static int Fn2( int n)
{
if (n <= 0)
{
throw new ArgumentOutOfRangeException();
}
int a = 1;
int b = 1;
for ( int i = 3; i <= n; i++)
{
b = checked(a + b); // when n>46 memory will overflow
a = b - a;
}
return b;
}
好了,這里應該是最優的方法了。
值得注意的是,我們要考慮內存泄漏問題,因為我們用int類型來保存Fibonacci的結果,所以n不能大於46(32位操作系統)
