随笔- 100  文章- 0  评论- 3  阅读- 30413 

1.什么情况下使用递归

  可以将一个问题分解为很多子问题

  这个问题的求解思路与子问题的思路完全一样

  有递归的终止条件

 

2.斐波那契

复制代码
package com.jun.algorithm.foundation.thought;

import org.junit.Test;

/**
 * 斐波那契
 * 递归的条件:
 * 一个问题可以分为几个子问题
 * 子问题的求解思路都是完全一样
 * 存在递归的终止条件
 * <p>
 * 这里将会一步步的优化
 * 先递归,然后循环,然后使用缓存,最后使用尾递归方式
 */
public class Fibonacci {
    /**
     * 递归方式
     * 时间复杂度:2^n
     */
    public int fab(int n) {
        if (n <= 2) {
            return 1;
        }
        return fab(n - 1) + fab(n - 2);
    }

    /**
     * 循环
     * 时间复杂度 n
     *
     * @param n
     */
    public int noFab(int n) {
        if (n <= 2) {
            return 1;
        }
        int a = 1;
        int b = 1;
        int c = 0;
        for (int i = 3; i <= n; i++) {
            c = a + b;
            a = b;
            b = c;
        }
        return c;
    }

    private int[] data = new int[6];

    /**
     * 使用缓存,计算过的不在计算了
     */
    public int fabWithArray(int n) {
        if (n <= 2) {
            return 1;
        }
        if (data[n] > 0) {
            return data[n];
        }
        int result = fabWithArray(n - 1) + fabWithArray(n - 2);
        data[n] = result;
        return result;
    }

    /**
     * 尾递归
     * 倒着算
     * 传递结果
     * preResult:上次的结果
     * result:当前的结果
     * <p>
     * 尾递归的条件:
     * 最后的返回,不要再做任何的操作
     */
    public int tailFab(int n, int preResult, int result) {
        if (n <= 2) {
            return result;
        }
        // 传递下去,再做一步计算
        return tailFab(n - 1, result, preResult + result);
    }

    @Test
    public void test() {
        int fab = fab(6);

        int noFab = noFab(6);
        System.out.println("noFab=" + noFab);
        System.out.println("fab=" + fab);

        int i = tailFab(6, 1, 1);
        System.out.println("fabWithArray=" + i);
    }
}
复制代码

 

 posted on   曹军  阅读(45)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享4款.NET开源、免费、实用的商城系统
· 全程不用写代码,我用AI程序员写了一个飞机大战
· MongoDB 8.0这个新功能碉堡了,比商业数据库还牛
· 白话解读 Dapr 1.15:你的「微服务管家」又秀新绝活了
· 上周热点回顾(2.24-3.2)
点击右上角即可分享
微信分享提示