zoukankan      html  css  js  c++  java
  • 斐波那契数列

    ##题目描述 大家都知道斐波那契数列,现在要求输入一个整数n,请你输出斐波那契数列的第n项(从0开始,第0项为0)。 n<=39

    思路

    1. 递归(函数栈调用消耗太高)
      时间复杂度O(2^n),空间复杂度O(n)。

    2. 使用循环替换递归
      时间复杂度O(n),空间复杂度O(1)。

    3. 动态规划
      时间复杂度O(n),空间复杂度O(1)。

    4. 矩阵快速幂


      时间复杂度O(lgn),空间复杂度O(1)。

    递归算法

    public class Solution {
        public int Fibonacci(int n) {
            if(n < 0)    return 0;
            if(n < 2)    return n;
            return Fibonacci(n-1)+Fibonacci(n-2);
        }
    }
    

    循环算法

    public class Solution {
        public int Fibonacci(int n) {
            int a = 0, b = 1, c = 1;
            while(n-- > 0) {
                a = b;
                b = c;
                c = a + b;
            }
            return a;
        }
    }
    

    动态规划

    public class Solution {
        public int Fibonacci(int n) {
            int[] dp = new int[] {0, 1};
            while(n-- > 0) {
                dp[1] = dp[0] + dp[1];
                dp[0] = dp[1] - dp[0];
            }
            return dp[0];
        }
    }
    

    矩阵快速幂

    class Solution {
        private int[][] matmul(int[][] a, int[][] b, int m, int n, int t) {
            int[][] tmp = new int[m][n];
            for(int i = 0; i < m; i++) {
                for(int j = 0; j < n; j++) {
                    tmp[i][j] = 0;
                    for(int k = 0; k < t; k++) {
                        tmp[i][j] += a[i][k] * b[k][j];
                    }
                }
            }
            return tmp;
        }
        
        public int Fibonacci(int n){
            if(n < 1)     return 0;
            if(n == 1)    return 1;
            int[][] matT = new int[][] {{1, 1}, {1, 0}};
            int[][] fibT = new int[][] {{1}, {0}};
            while(n > 1){
                // 二进制转换,最高位1用最终快速幂矩阵,其余位1用当前幂矩阵
                if(n%2 == 1){
                    fibT = matmul(matT, fibT, 2, 1, 2);
                }
                matT = matmul(matT, matT, 2, 2, 2);
                n /= 2;
            }
            fibT = matmul(matT, fibT, 2, 1, 2);
            return fibT[1][0];
        }
    }
    

    简单快速幂求2的n次方

    class Solution {
        public long pow(int n) {
            long ans = 1, base = 2;
            while(n > 0) {
                if(n%2 == 1) {
                    ans = (ans * base) % 1000000007;
                }
                base = (base * base) % 1000000007;
                n >>= 1;
            }
            return ans;
        }
    }
    

    笔记

    1.快速幂余项的个数联想二进制权重
    2.循环实现,三次赋值,一次加法
    dp实现,两次赋值,一次加法,一次减法
    后者效率未见得高
    3.尾递归优化

  • 相关阅读:
    UOS ROOT如何SSH登陆
    UOS打印日志提示Can’t create temporary file,无法打印如何处理
    UOS简易OEM ISO镜像的步骤(UOS如何自行定制镜像文件)
    UOS火狐浏览器如何下载并安装Adobe Flash Player插件【AMD】
    UOS如何录制屏幕视频
    UOS怎么进入到单用户模式
    UOS免密访问windows共享文件夹
    UOS命令行服务器离线授权码激活步骤
    UOS怎么安装搜狗拼音输入法【x86】
    UOS如何安装RTX客户端-更新版(X86)
  • 原文地址:https://www.cnblogs.com/ustca/p/12312521.html
Copyright © 2011-2022 走看看