技术提高是一个循序渐进的过程,所以我讲的leetcode算法题从最简单的level开始写的,然后> 到中级难度,最后到hard难度全部完。目前我选择C语言,Python和Java作为实现语言,因为这三种语言还是比较典型的。由于篇幅和> 精力有限,其他语言的实现有兴趣的朋友请自己尝试。
如果有任何问题可以在文章后评论或者私信给我。
如果有朋友希望我讲些其他话题,请在评论区留言或者私信给我。
持续分享,敬请关注。
LeetCode 1137. 求第N个泰波拿契数(N-th Tribonacci Number)
问题描述:
注:
- 0 <= n <= 37;
- 答案是一个32位整数,即。res <= 2^31 - 1;
示例:
C语言实现:
泰波拿契数是斐波那契数的扩展。它的求法与求斐波那契数类似,但是要复杂一些。
方法一:递归或者循环
我们依然可以用循环或者递归,像求斐波那契数那样求泰波拿契数。
我这里只说递归方法,因为递归代码要更简洁一些。
一个泰波拿契数是它前面的3个数的和,所以对于前3个数(0,1,1)我们直接赋值,无需计算。
其他的则返回 tribonacci(n-3) + tribonacci(n-2) + tribonacci(n-1)。
但是这里要注意,如果简单的这样处理,那么会有大量的重复计算。当n增大,效率会迅速下降。
为了避免重复计算,对于已经计算过的数,要存起来,下次用的时候直接取。鉴于题目要求n不大于37,所以我们定义一个长度时38的数组T来保存这些数。
方法二:通项公式
在前面我讲,如何求第n个斐波那契数时,我提到了用数列的通项公式一次求出。在这里我们试着求出泰波拿契数的通项公式。
对于一个泰波拿契数数列,我们可以得出如下的关系:
可以得到A的特征方程:
解这个一元三次方程得到它的3个解, α,β 和 γ :
其种 α 是唯一的实根,是一个无理数。
β 和 γ 是两个共轭复数根。
因此它的比内公式表示为:
(篇幅有限,关于其比内公式的推导,见https://www.mscs.dal.ca/FQ/Scanned/20-2/spickerman.pdf)
第一次看到这个公式很错愕,无理数和复数的和得到一个整实数,多么神奇。
看到这里的朋友一定很好奇算法怎么实现。
其实该比内公式的后两项对结果的影响非常小,只对Tn的精度有非常小的影响,我们可以简化成:
这个符号表示对结果进行四舍五入。我实际测试的结果: 对n小于57的任意Tn 都不受影响。完全满足题目要求。
两种算法的代码如下:
Java语言实现:
Java 的实现和C语言的实现一致,不再撰述。
代码如下:
Python语言实现:
Python 的实现和C语言的实现一致,不再撰述。
代码如下: