Fibonacci numbers

news/2024/7/3 14:15:41

Program for Fibonacci numbers

The Fibonacci numbers are the numbers in the following integer sequence.

0, 1, 1, 2, 3, 5, 8, 13, 21, 34, 55, 89, 141, ……..

In mathematical terms, the sequence Fn of Fibonacci numbers is defined by the recurrence relation

    Fn = Fn-1 + Fn-2

with seed values

   F0 = 0 and F1 = 1. 


We strongly recommend that you click here and practice it, before moving on to the solution.


Write a function int fib(int n) that returns Fn. For example, if n = 0, then fib() should return 0. If n = 1, then it should return 1. For n > 1, it should return Fn-1 + Fn-2

Following are different methods to get the nth Fibonacci number.

Method 1 ( Use recursion ) 
A simple method that is a direct recusrive implementation mathematical recurance relation given above.

#include<stdio.h>
int fib( int n)
{
    if (n <= 1)
       return n;
    return fib(n-1) + fib(n-2);
}
 
int main ()
{
   int n = 9;
   printf ( "%d" , fib(n));
   getchar ();
   return 0;
}

Time Complexity: T(n) = T(n-1) + T(n-2) which is exponential.
We can observe that this implementation does a lot of repeated work (see the following recursion tree). So this is a bad implementation for nth Fibonacci number.

                         fib(5)   
                     /             \     
               fib(4)                fib(3)   
             /      \                /     \
         fib(3)      fib(2)         fib(2)    fib(1)
        /     \        /    \       /    \  
  fib(2)   fib(1)  fib(1) fib(0) fib(1) fib(0)
  /    \
fib(1) fib(0)

Extra Space: O(n) if we consider the function call stack size, otherwise O(1).

Method 2 ( Use Dynamic Programming )
We can avoid the repeated work done is the method 1 by storing the Fibonacci numbers calculated so far. 

#include<stdio.h>
 
int fib( int n)
{
   /* Declare an array to store Fibonacci numbers. */
   int f[n+1];
   int i;
 
   /* 0th and 1st number of the series are 0 and 1*/
   f[0] = 0;
   f[1] = 1;
 
   for (i = 2; i <= n; i++)
   {
       /* Add the previous 2 numbers in the series
          and store it */
       f[i] = f[i-1] + f[i-2];
   }
 
   return f[n];
}
 
int main ()
{
   int n = 9;
   printf ( "%d" , fib(n));
   getchar ();
   return 0;
}

Time Complexity: O(n)
Extra Space: O(n)

Method 3 ( Space Otimized Method 2 )
We can optimize the space used in method 2 by storing the previous two numbers only because that is all we need to get the next Fibannaci number in series.

#include<stdio.h>
int fib( int n)
{
   int a = 0, b = 1, c, i;
   if ( n == 0)
     return a;
   for (i = 2; i <= n; i++)
   {
      c = a + b;
      a = b;
      b = c;
   }
   return b;
}
 
int main ()
{
   int n = 9;
   printf ( "%d" , fib(n));
   getchar ();
   return 0;
}

Time Complexity: O(n)
Extra Space: O(1)

Method 4 ( Using power of the matrix {{1,1},{1,0}} )
This another O(n) which relies on the fact that if we n times multiply the matrix M = {{1,1},{1,0}} to itself (in other words calculate power(M, n )), then we get the (n+1)th Fibonacci number as the element at row and column (0, 0) in the resultant matrix.

The matrix representation gives the following closed expression for the Fibonacci numbers:
fibonaccimatrix

#include <stdio.h>
 
/* Helper function that multiplies 2 matricies F and M of size 2*2, and
   puts the multiplication result back to F[][] */
void multiply( int F[2][2], int M[2][2]);
 
/* Helper function that calculates F[][] raise to the power n and puts the
   result in F[][]
   Note that this function is desinged only for fib() and won't work as general
   power function */
void power( int F[2][2], int n);
 
int fib( int n)
{
   int F[2][2] = {{1,1},{1,0}};
   if (n == 0)
       return 0;
   power(F, n-1);
 
   return F[0][0];
}
 
void multiply( int F[2][2], int M[2][2])
{
   int x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];
   int y =  F[0][0]*M[0][1] + F[0][1]*M[1][1];
   int z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];
   int w =  F[1][0]*M[0][1] + F[1][1]*M[1][1];
 
   F[0][0] = x;
   F[0][1] = y;
   F[1][0] = z;
   F[1][1] = w;
}
 
void power( int F[2][2], int n)
{
   int i;
   int M[2][2] = {{1,1},{1,0}};
 
   // n - 1 times multiply the matrix to {{1,0},{0,1}}
   for (i = 2; i <= n; i++)
       multiply(F, M);
}
 
/* Driver program to test above function */
int main()
{
   int n = 9;
   printf ( "%d" , fib(n));
   getchar ();
   return 0;
}


Time Complexity:
 O(n)
Extra Space: O(1)

Method 5 ( Optimized Method 4 )
The method 4 can be optimized to work in O(Logn) time complexity. We can do recursive multiplication to get power(M, n) in the prevous method (Similar to the optimization done in this post)

#include <stdio.h>
 
void multiply( int F[2][2], int M[2][2]);
 
void power( int F[2][2], int n);
 
/* function that returns nth Fibonacci number */
int fib( int n)
{
   int F[2][2] = {{1,1},{1,0}};
   if (n == 0)
     return 0;
   power(F, n-1);
   return F[0][0];
}
 
/* Optimized version of power() in method 4 */
void power( int F[2][2], int n)
{
   if ( n == 0 || n == 1)
       return ;
   int M[2][2] = {{1,1},{1,0}};
 
   power(F, n/2);
   multiply(F, F);
 
   if (n%2 != 0)
      multiply(F, M);
}
 
void multiply( int F[2][2], int M[2][2])
{
   int x =  F[0][0]*M[0][0] + F[0][1]*M[1][0];
   int y =  F[0][0]*M[0][1] + F[0][1]*M[1][1];
   int z =  F[1][0]*M[0][0] + F[1][1]*M[1][0];
   int w =  F[1][0]*M[0][1] + F[1][1]*M[1][1];
 
   F[0][0] = x;
   F[0][1] = y;
   F[1][0] = z;
   F[1][1] = w;
}
 
/* Driver program to test above function */
int main()
{
   int n = 9;
   printf ( "%d" , fib(9));
   getchar ();
   return 0;
}

Time Complexity: O(Logn)
Extra Space: O(Logn) if we consider the function call stack size, otherwise O(1).

Please write comments if you find the above codes/algorithms incorrect, or find other ways to solve the same problem.

References:
http://en.wikipedia.org/wiki/Fibonacci_number
http://www.ics.uci.edu/~eppstein/161/960109.html


http://www.niftyadmin.cn/n/4388306.html

相关文章

HTML DOM详细知识

1&#xff1a;节点 HTML DOM中&#xff0c;所有的事物都是节点。 整个文档是一个文档节点&#xff1b; 每个HTML元素是一个元素节点&#xff1b; 每个元素内的文本是一个文本节点&#xff1b; 每个属性是一个属性节点&#xff1b; 每个注释是一个注释节点&#xff1b; 2&#x…

PCI简介(二)

2019独角兽企业重金招聘Python工程师标准>>> 1.x86处理器系统地址空间简介 1.1 CPU地址空间 CPU地址空间是指CPU所能寻址的空间大小&#xff0c;比如对于32位CPU来说&#xff0c;其所能寻址的空间大小为0~4G。这是由CPU自身的地址总线数目决定的。这段空间也被称作C…

数组总结,持续更新~

数组的基础方法&#xff0c;就不一一介绍了&#xff0c;这里会介绍一些常用的ES6的一些常用方法&#xff0c; 在这之前&#xff0c;先说一些数组的常见问题。 1 数组的构建 数组的普通调用&#xff0c;等于构造调用。 下面的3种方式&#xff0c;都是一样的。 let arr Array(1,…

小程序中form 表单提交和取值方法

我们直接给 input 添加 bindinput,比如:<input bindinput="onUsernameInput" />,可以在 onUsernameInput 中直接使用 e.detail.value,即: onUsernameInput : function(e) { e.detail.value; } 但是,如果有多个输入控件,我们不可能为每个控件添加 bind…

java dateformat 24_java – (简单)DateFormat,允许24:00:00和00:00:00作为输入

值24:00未在LocalTime中表示,因为它严格地是第二天的一部分.考虑到24:00可以表示为LocalTime的一部分的模型,但结论是它在很多用例中会非常混乱,并且会产生比它解决的更多错误.但是在java.time中支持24:00.完全可以使用标准格式化技术对其进行解析,但是必须使用SMART或LENIENT模…

python使用yaml库读取和写入数据

import yamltest.yml文件数据&#xff1a;yaml_path r"D:\PycharmProjects\2020study\BBBstudy\test.yml" with open(yaml_path, r) as f:cfg f.read()print(cfg)# 此时读出来的数据是字符串print(type(cfg))# 用yaml.load方法转字典d yaml.load(cfg)print(d)prin…

lambda函数复习

def test(x):return x*x # 这里我们用lambda定义一个匿名的内联函数。请注意&#xff0c;该函数没有名称。test 是保存创建的lambda函数的变量的名称 # 上面的函数和下面的lambda函数是一样的 test_f lambda x: x*x print(test(3)) print(test_f(3)) # 常量函数 def constant(…

java serializable用法_java基础----gt;Serializable的使用

Serializable序列化的简要说明一、 持久化的简单介绍&#xff1a;“持久化”意味着对象的“生存时间”并不取决于程序是否正在执行——它存在或“生存”于程序的每一次调用之间。通过序列化一个对象&#xff0c;将其写入磁盘&#xff0c;以后在程序再次调用时重新恢复那个对象&…