方法1:通过循环递增获得结果 时间复杂度O(n)
class Solution {
public:
/*
* @param n: an integer
* @return: an ineger f(n)
*/
int fibonacci(int n) {
int f1 = 0;
int f2 = 1;
int end = 0;
int i;
for(i = 2;i < n;i++)
{
end = f1+f2;
f1 = f2;
f2 = end;
}
switch (n)
{
case 1:
{
return f1;
}
case 2:
{
return f2;
}
default:
{
return end;
}
}
}
};
方法2 通过矩阵把问题转换为矩阵次幂的问题,然后通过矩阵次幂可以转换为二进制的数值从而减少循环次数的方法降低时间复杂度至O(log(2)N),该逻辑可以延伸之任意的次幂都可以使用二进制表示,降低计算量如7次幂则为111,则4次幂×2次幂×一次幂
class Solution {
public:
int fibonacci(int n);
private:
int** multiply(int** a,int** b);
};
int ** Solution::multiply(int** a,int** b)
{
int ** result = new int*[2];
result[0] = new int[2];
result[1] = new int[2];
result[0][0] = a[0][0]*b[0][0]+a[0][1]*b[1][0];
result[0][1] = a[0][0]*b[0][1]+a[0][1]*b[1][1];
result[1][0] = a[1][0]*b[0][0]+a[1][1]*b[1][0];
result[1][1] = a[1][0]*b[0][1]+a[1][1]*b[1][1];
return result;
}
int Solution::fibonacci(int n) {
if(n == 1)
{
return 0;
}
else
{
int i;
//单位矩阵
int** unit = new int*[2];
for(i = 0;i<2;i++)
{
unit[i] = new int[2];
}
unit[0][0] = 1;
unit[0][1] = 0;
unit[1][0] = 0;
unit[1][1] = 1;
int ** result = unit;
//初始矩阵
int** init = new int*[2];
for(i = 0;i<2;i++)
{
init[i] = new int[2];
}
init[0][0] = 1;
init[0][1] = 1;
init[1][0] = 1;
init[1][1] = 0;
int **iterator = init;//迭代递增矩阵
int cover = n-1-1;//次幂
while(cover != 0)
{
if(cover & 1 == 1)
{
result = multiply(result,iterator);
}
iterator = multiply(iterator,iterator);
cover = cover>>1;
}
return result[0][0];
}
}
代码注释不多不一定能看懂(我在里面的multiply中放入了一个矩阵乘法,因为Lintcode似乎不允许使用其他的库,所以矩阵的代码只能自己写,非常的简易),重要的是原理,请自行搜索斐波那契数列的矩阵算法。
认知:①二维数组和一维数组初始化的区别,②二维(及以上)数组和一维数组向函数传参时的区别,③复习了一下数组指针
④复习了一下指针数组⑤复习了二级指针和数组指针的不同(前者指向一个一级指针,后者指向一个数组,但他们都能在逻辑上构建一个二维数组)