java算法实例_优化斐波那契数列

一、动态规划、分治、递归的概念

     动态规划:如果大问题分解为很多小问题后,小问题有互相重叠部分,则用递归的思路来分析问题,再使用存储中间结果+循环的思路来写代码!动态规划的三个特征:适用于最优解问题、有大量的重复子问题、子问题之间有依赖(不独立)

     与递归的关系:这些重复的子问题,DP算法将其结果用一维或二维数组(邻接矩阵)保存下来,等下一次又要计算该子问题时,直接用已计算好的;而递归却不是这样,它会一遍又一遍地计算这些重复的子问题,从而效率狂降。子问题重复率较高的递归算法可改写成动态规划,但不是所有递归算法都适合改成动态规划。

     与分治的关系:在分治法中,有大量的重复子问题,且它们之间无依赖。

二、优化斐波那契数列

package me.ele;

/**
 * 动态规划的两种类型
 * 1.自顶向下的动态规划实现:用的递归。
 * 2.自底向上的动态规划实现:用的迭代。
 *
 * @author LZJ
 * @create 2018-09-29 17:29
 **/
public class Fibonacci {

    /**
     * 普通的递归实现的动态规划:效率特别低,有大量的重复计算,指数级的时间复杂度。
     *
     * @param n
     * @return
     */
    public static int fibonacci01(int n) {
        if (n == 0)
            return 0;
        if (n == 1)
            return 1;
        return fibonacci01(n - 1) + fibonacci01(n - 2);
    }

    /**
     * 自底向上的动态规划实现:会记录重复子问题结果的改进版迭代。
     * 只要有存储已经计算出的值的空间,就能把这项技术应用到任何递归计算中,就能把算法从指数级运行时间向线性时间改进。
     *
     * @param n
     * @return
     */
    public static long fibonacci02(int n) {
        long temp[] = new long[n];
        temp[0] = 0;
        temp[1] = 1;
        for (int i = 2; i < n; ++i) {
            temp[i] = temp[i - 1] + temp[i - 2];
        }
        return temp[n - 1];
    }

    public static long[] mArray;

    /**
     * 自顶向下的动态规划实现:会记录重复子问题结果的改进版递归。存储它所计算的每一个值(正如下方代码最末的步骤),
     * 并通过检查所存储的值,来避免重新计算它们的任何项(正如最初的步骤)。
     *
     * @param n
     * @return
     */
    public static long fibonacci03(int n) {
        //不等于初始值0,则表示该元素已经求解过了,直接用其值即可。
        if (mArray[n] != 0) {
            return mArray[n];
        }
        //完成按着递推式来写逻辑,即可!
        if (n == 0) {
            return mArray[n] = 0;
        }
        if (n == 1) {
            return mArray[n] = 1;
        } else {
            return mArray[n] = fibonacci03(n - 1) + fibonacci03(n - 2);
        }
    }

    public static void main(String[] args) {
        int n = 1000;

//        System.out.prlongln("===========");
//        long start = System.currentTimeMillis();
//        System.out.prlongln("start time:" + start);
//        long fibonacci01 = fibonacci01(n);
//        System.out.prlongln(fibonacci01);
//        long end = System.currentTimeMillis();
//        System.out.prlongln("end time:" + end + "间隔时间:" + (end - start));

        System.out.println("===========");
        long start2 = System.currentTimeMillis();
        long fibonacci02 = fibonacci02(n + 1);
        System.out.println(fibonacci02);
        long end2 = System.currentTimeMillis();
        System.out.println("end time:" + end2 + "间隔时间:" + (end2 - start2));

        System.out.println("===========");
        mArray = new long[n + 1];
        long start3 = System.currentTimeMillis();
        long fibonacci03 = fibonacci03(n);
        System.out.println(fibonacci03);
        long end3 = System.currentTimeMillis();
        System.out.println("end time:" + end3 + "间隔时间:" + (end3 - start3));

    }

}
  • 1
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值