The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such that each number is the sum of the two preceding ones, starting from 0 and 1. That is,

  1. F(0) = 0,   F(1) = 1
  2. F(N) = F(N - 1) + F(N - 2), for N > 1.

Given N, calculate F(N).

Example 1:

  1. Input: 2
  2. Output: 1
  3. Explanation: F(2) = F(1) + F(0) = 1 + 0 = 1.

Example 2:

  1. Input: 3
  2. Output: 2
  3. Explanation: F(3) = F(2) + F(1) = 1 + 1 = 2.

Example 3:

  1. Input: 4
  2. Output: 3
  3. Explanation: F(4) = F(3) + F(2) = 2 + 1 = 3.

Note:

0 ≤ N ≤ 30.

这道题是关于斐波那契数列的,这个数列想必我们都听说过,简而言之,除了前两个数字之外,每个数字等于前两个数字之和。举个生动的例子,大学食堂里今天的汤是昨天的汤加上前天的汤。哈哈,是不是瞬间记牢了。题目没让返回整个数列,而是直接让返回位置为N的数字。那么还是要构建整个斐波那契数组,才能知道位置N上的数字。像这种有规律有 pattern 的数组,最简单的方法就是使用递归啦,先把不合规律的前两个数字处理了,然后直接对 N-1 和 N-2 调用递归,并相加返回即可,参见代码如下:

解法一:

  1. class Solution {
  2. public:
  3. int fib(int N) {
  4. if (N <= ) return N;
  5. return fib(N - ) + fib(N - );
  6. }
  7. };

上面的写法虽然简单,但是并不高效,因为有大量的重复计算,我们希望每个值只计算一次,所以可以使用动态规划 Dynamic Programming 来做,建立一个大小为 N+1 的 dp 数组,其中 dp[i] 为位置i上的数字,先初始化前两个分别为0和1,然后就可以开始更新整个数组了,状态转移方程就是斐波那契数组的性质,最后返回 dp[N] 即可,参见代码如下:

解法二:

  1. class Solution {
  2. public:
  3. int fib(int N) {
  4. vector<int> dp(N + );
  5. dp[] = ; dp[] = ;
  6. for (int i = ; i <= N; ++i) {
  7. dp[i] = dp[i - ] + dp[i - ];
  8. }
  9. return dp[N];
  10. }
  11. };

我们可以对上面解法进行空间上的进一步优化,由于当前数字只跟前两个数字有关,所以不需要保存整个数组,而是只需要保存前两个数字就行了,前一个数字用b表示,再前面的用a表示。a和b分别初始化为0和1,代表数组的前两个数字。然后从位置2开始更新,先算出a和b的和 sum,然后a更新为b,b更新为 sum。最后返回b即可,参见代码如下:

解法三:

  1. class Solution {
  2. public:
  3. int fib(int N) {
  4. if (N <= ) return N;
  5. int a = , b = ;
  6. for (int i = ; i <= N; ++i) {
  7. int sum = a + b;
  8. a = b;
  9. b = sum;
  10. }
  11. return b;
  12. }
  13. };

给下面的这种解法跪了,直接 hardcode 了所有N范围内的斐波那契数字,然后直接返回,这尼玛诸葛孔明的棺材板快压不住了。。。我从未见过如此。。。

解法四:

  1. class Solution {
  2. public:
  3. int fib(int N) {
  4. vector<int> fibs{, , , , , , , , , , , , , , , , , , , , , , , , , , , , , , };
  5. return fibs[N];
  6. }
  7. };

Github 同步地址:

https://github.com/grandyang/leetcode/issues/509

类似题目:

Split Array into Fibonacci Sequence

Length of Longest Fibonacci Subsequence

参考资料:

https://leetcode.com/problems/fibonacci-number/

https://leetcode.com/problems/fibonacci-number/discuss/215992/Java-Solutions

https://leetcode.com/problems/fibonacci-number/discuss/216245/Java-O(1)-time

LeetCode All in One 题目讲解汇总(持续更新中...)

[LeetCode] Fibonacci Number 斐波那契数字的更多相关文章

  1. 509. Fibonacci Number斐波那契数列

    网址:https://leetcode.com/problems/fibonacci-number/ 原始的斐波那契数列 运用自底向上的动态规划最佳! 可以定义vector数组,但是占用较多内存空间 ...

  2. 【LeetCode每天一题】Fibonacci Number(斐波那契数列)

    The Fibonacci numbers, commonly denoted F(n) form a sequence, called the Fibonacci sequence, such th ...

  3. 【LeetCode】1414. 和为 K 的最少斐波那契数字数目 Find the Minimum Number of Fibonacci Numbers Whose Sum Is K

    作者: 负雪明烛 id: fuxuemingzhu 个人博客:http://fuxuemingzhu.cn/ 目录 题目描述 题目大意 解题方法 贪心 日期 题目地址:https://leetcode ...

  4. 【C++】【斐波那契】求第几个斐波那契数字。

    首先在头文件 whichfibonaccinumber.h 中写了一个使用加法的解法.没有验证输入数字是否小于0. #ifndef WHICHFIBONACCINUMBER_H_ #define WH ...

  5. 10、end关键字和Fibonacci series: 斐波纳契数列

    # Fibonacci series: 斐波纳契数列 # 两个元素的总和确定了下一个数 a, b = 0, 1 #复合赋值表达式,a,b同时赋值0和1 while b < 10: print(b ...

  6. Callable接口使用以及计算斐波那契数字的数值总和

    一.简单使用 Runnable是执行工作的独立任务,但是它不返回任何值.如果你希望任务完成的时能够返回一个值,那么可以实现一个Callable接口.在Java SE5中引入的Callable是一种具有 ...

  7. [Amazon] Program for Fibonacci numbers 斐波那契数列

    The Fibonacci numbers are the numbers in the following integer sequence. 0, 1, 1, 2, 3, 5, 8, 13, 21 ...

  8. fibonacci数列-斐波那契数列-python编程

    未完待续~ 了解fibonacci数列: 斐波纳契数列(Fibonacci Sequence),又称黄金分割数列. 1,1,2,3,5,8,13,21,34,55,89,144,233,377,610 ...

  9. Fibonacci series(斐波纳契数列)的几种常见实现方式

    费波那契数列的定义: 费波那契数列(意大利语:Successione di Fibonacci),又译费波拿契数.斐波那契数列.斐波那契数列.黄金切割数列. 在数学上,费波那契数列是以递归的方法来定义 ...

随机推荐

  1. 2018-2019-2 20165221『网络对抗技术』Exp4:恶意代码分析

    2018-2019-2 20165221『网络对抗技术』Exp4:恶意代码分析 实验要求: 是监控你自己系统的运行状态,看有没有可疑的程序在运行. 是分析一个恶意软件,就分析Exp2或Exp3中生成后 ...

  2. 2018-2019-2 20175204 张湲祯 实验二《Java面向对象程序设计》实验报告

    2018-2019-2-20175204 张湲祯 实验二 <Java开发环境的熟悉>实验报告 实验二 Java面向对象程序设计 一.实验内容: 初步掌握单元测试和TDD 理解并掌握面向对象 ...

  3. codeforces 343D 树剖后odt维护

    子树修改+路径修改+单点查询 树链剖分+区间维护即可 由于只有单点查询,我直接用了odt,复杂度还行 #include<bits/stdc++.h> #define endl '\n' # ...

  4. 04mycat数据切分

    自定义切分文件 [root@mycat mycat]# cat conf/customer-hash-int.txt 101=0 102=0 103=0 104=1 105=1 106=1 Rule. ...

  5. 彻底搞懂 C# 的 async/await

    前言 Talk is cheap, Show you the code first! private void button1_Click(object sender, EventArgs e) { ...

  6. Uni-app页面生命周期

    学习任何框架必须将其生命周期了然于胸. uni-app支持如下页面生命周期函数: onLoad 监听页面加载,其参数为上个页面传递的数据,参数类型为object(用于页面传参),示例中可参考 onSh ...

  7. TLS详解

    TLS加密通信, 开始使用协商的秘钥进行加密通信 1.服务器也可以要求验证客户端,即实现双向的验证, 2.会话缓存握手过程,为了建立握手的速度,减少协议带来的性能方面的降低和资源方面的消耗,TLS协议 ...

  8. kubernets helm 如何删除tiller

    https://stackoverflow.com/questions/53612553/how-to-uninstall-remove-tiller-from-kubernetes-manually ...

  9. 《ServerSuperIO Designer IDE使用教程》-2.与硬件网关数据交互,并进行数据级联转发,直到云端。发布:v4.2.1版本

    v4.2.1 更新内容:1.重新定义数据转发文本协议,使网关与ServerSuperIO以及之间能够相关交互数据.2.扩展ServerSuperIO动态数据类的方法,更灵活.3.修复Designer增 ...

  10. java时间处理,获取当前时间的小时,天,本周周几,本周周一的日期,本月一号的日期

    1.时间转时间戳 public static long strToTimestamp(String dateTimeStr) throws Exception { Timestamp time = T ...