时间复杂度(斐波那契数列演变)

常见的算法的时间复杂度分为:
1,常数阶
常数阶算法运行的次数是一个常数,如5、20、100。常数阶算法时间复杂度通常用O(1)表示。例如:

/**
  * 时间复杂度为O(1)
  */
private void test(int i, int j) {
        i = i ^ j;
        j = i ^ j;
        i = i ^ j;
        System.out.println(i + "--" + j);
}

2,多项式阶
很多算法时间复杂度是多项式,通常用O(n)、O(n²)、O(n³)等表示。例如:

 /**
  * 时间复杂度为O(n²)
  */
private void test(int n) {
        int sum = 0;
        for (int i = 0; i < n; i++) {
            for (int j = 0; j < n; j++) {
                sum++;
            }
        }
        System.out.println(sum);
}
    /**
     * 计算后一个格子里的数量是前一个格子数量的两倍 求总和
     * 尾递归 时间复杂度为O(n)  空间复杂度为0(n)  
     *
     * @param start 每次增加的数量 初始第一个格子为1
     * @param n     n个格子
     * @param sum   总和
     * @return 总数
     */
    private long test(int start, int n, int sum) {
        if (n < 0) {
            return sum;
        } else {
            return test(2 * start, --n, sum += start);
        }
    }

3,指数阶
指数阶时间复杂度运行效率极差,程序往往像躲“魔鬼”一样避开它,常见的有O(2n)、O(n!)、O(nn)等。使用这样的算法需要谨慎,例如斐波那契数列的正常递归实现

4,对数阶
对数阶时间复杂度运行效率较高,常见的有O(logn),O(nlogn)等,例如:

    /**
     * 时间复杂度为O(log2n)
     */
    private long test(int n) {
        int i = 1;
        while (i < n) {
            i = i * 2;
        }
        return i;
    }

时间复杂度的大致排序为:
O(1)<O(logn)<O(n)<O(nlogn)<O(n²)<O(n³)<O(2n)<O(n!)<O(nn)

斐波那契数列
后一项是前两项之和, 1 1 2 3 5 8 13
1,指数阶实现:

    /**
     * 递归实现 (最后就是一堆1 相加)
     *  时间复杂度 0(n)=0(n-1)+O(n-2)+1
     * @param n 要获得的第几项的值
     * @return 返回第n项的值
     */
    private int fibonacciSequence(int n) {
        if (n == 1 || n == 2) {
            return 1;
        } else {
            return fibonacciSequence(n - 1) + fibonacciSequence(n - 2);
        }
    }

2,多项式阶实现:

/**
     * 时间复杂度为O(n) 同时空间复杂度也为O(n)
     *
     * @param n 要获得的第几项的值
     * @return 返回第n项的值
     */
    private int fibonacciSequence(int n) {
        if (n < 1) {
            return -1;
        }
        int[] a = new int[n];
        a[0] = 1;
        a[1] = 1;
        for (int i = 2; i < n; i++) {
            a[i] = a[i - 1] + a[i - 2];
        }
        return a[n - 1];
    }

算法优化(也可以使用尾递归):

/**
     * 时间复杂度为O(n) 空间复杂度为O(1)
     *
     * @param n 要获得的第几项的值
     * @return 返回第n项的值
     */
    private int fibonacciSequence(int n) {
        int s1, s2;
        if (n < 1) {
            return -1;
        }
        if (n == 1 || n == 2) {
            return 1;
        }
        s1 = 1;
        s2 = 1;
        for (int i = 2; i < n; i++) {
            s2 = s1 + s2;
            s1 = s2 - s1;
        }
        return s2;
    }

3,对数阶


//fibonacciSequence(1,0,0,6)

/**
     * 时间复杂度 O(logn)  空间复杂度O(1)
     *
     * @param a
     * @param b
     * @param p
     * @param q
     * @param count 要取的位置
     * @return 要取的位置数字
     */
    private int fibonacciSequence(int a, int b, int p, int q, int count) {
        if (count == 0) {
            return b;
        } else if (count % 2 != 0) {
            return fibonacciSequence(b * p + a * q + a * p, b * p + a * q, p, q, count - 1);
        } else {
            return fibonacciSequence(a, b, p * p + q * q, q * q + 2 * p * q, count / 2);
        }
    }
最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。