斐波那契数列问题(java语言)
斐波那契数列:指的是这样一个数列:0、1、1、2、3、5、8、13、21、34、……在数学上,斐波那契数列以如下被以递推的方法定义:F(0)=0,F(1)=1,F(n)=F(n-1)+F(n-2)(n ≥ 2,n ∈ N*)
package com.txw.javaCore.server.leetcode.dp;
import lombok.extern.slf4j.Slf4j;
import java.util.HashMap;
/**
* @PROJECT_NAME: DP
* @DESCRIPTION: 动态规划解题套路框架
* 1.动态规划问题的一般形式就是求最值
* 2.求解动态规划的核心问题是穷举
* 3.动态规划三要素:重叠子问题、最优子结构、状态转移方程
* <p>
* 思考:
* 1.DP问题的base case(最简单情况)是什么?
* 2.DP问题有什么“状态”?
* 3.对于每个“状态”,可以做出什么“选择”使得“状态”发生改变?
* 4.如何定义dp数组/函数的含义来表现“状态”和“选择”
* <p>
* 总结:状态、选择、dp数组的定义
* @Author: wx:xiaoxuanwu_9703
* @DATE: 2021/3/30 14:40
*/
@Slf4j
public class DpFrame {
/**
* 1.斐波那契数列-暴力递归
*
* @param num
* @return
*/
public static int blFib(int num) {
if (0 == num) {
return 0;
}
if (1 == num || 2 == num) {
return 1;
}
return blFib(num - 1) + blFib(num - 2);
}
/**
* 2.斐波那契数列-带备忘录的递归解法
*
* @param num
* @return
*/
public static int bwlFib(int num) {
if (0 == num) {
return 0;
}
//备忘录hashmap
HashMap<Integer, Integer> memo = new HashMap<>();
//将备忘录全部初始化为0
for (int i = 0; i <= num; i++) {
memo.put(i, 0);
}
//进行带备忘录的递归
return helper(memo, num);
}
public static int helper(HashMap<Integer, Integer> memo, int num) {
if (1 == num || 2 == num) {
return 1;
}
//已经计算过了
if (0 != memo.get(num)) {
return memo.get(num);
}
memo.put(num, helper(memo, num - 1) + helper(memo, num - 2));
return memo.get(num);
}
/**
* 3.斐波那契数列-dp数组的迭代解法
*
* @param num
* @return
*/
public static int dpFib(int num) {
if (0 == num) {
return 0;
}
if (1 == num || 2 == num) {
return 1;
}
/**DP table*/
HashMap<Integer, Integer> dp = new HashMap<>(num + 1);
//将备忘录全部初始化为0
for (int i = 0; i <= num; i++) {
dp.put(i, 0);
}
//base case
dp.put(1, 1);
dp.put(2, 1);
for (int i = 3; i <= num; i++) {
dp.put(i, dp.get(i - 1) + dp.get(i - 2));
}
return dp.get(num);
}
/**
* 4.斐波那契数列-基于dp数组的迭代解法,将空间复杂度降为O(1)
*
* @param num
* @return
*/
public static int dpPreFib(int num) {
if (0 == num) {
return 0;
}
if (1 == num || 2 == num) {
return 1;
}
//dp[n-2]
int prev = 1;
//dp[n-1]
int curr = 1;
for (int i = 3; i <= num; i++) {
int sum = prev + curr;
prev = curr;
curr = sum;
}
return curr;
}
public static void main(String[] args) {
log.info("--斐波那契数列-暴力递归:{}", blFib(6));
log.info("--斐波那契数列-带备忘录的递归解法:{}", bwlFib(7));
log.info("--斐波那契数列-dp数组的迭代解法:{}", dpFib(8));
log.info("--斐波那契数列-基于dp数组的迭代解法,将空间复杂度降为O(1):{}", dpPreFib(9));
}
}
运行结果: