[算法]---斐波那契数列模型

目录

[1. 第N个泰波那契数](#1. 第N个泰波那契数)

[1.1 解题思路](#1.1 解题思路)

[1.2 代码实现](#1.2 代码实现)

[2. 三步问题](#2. 三步问题)

[2.1 解题思路](#2.1 解题思路)

[2.2 代码实现](#2.2 代码实现)

[3. 使用最小花费爬楼梯](#3. 使用最小花费爬楼梯)

[3.1 解题思路](#3.1 解题思路)

[3.2 代码实现](#3.2 代码实现)

[4. 解码方法](#4. 解码方法)

[4.1 解题思路](#4.1 解题思路)

[4.2 代码实现](#4.2 代码实现)


1. 第N个泰波那契数

题目链接

1.1 解题思路

我们可以使用递归来解决这道题,但是递归中有重复的运算,给一个数找到这个数的泰波那锲数,这里我们可以利用动态规划设置一个dp数组来记录这些计算过的数,直接在数组里面找这些重复计算的结果。

1.2 代码实现

使用动态规划解决的代码:

java 复制代码
class Solution {
    public int tribonacci(int n) {
        //1 创建dp表
        //2 初始化dp表
        //3 填表
        //4 返回结果

        //处理边界条件
        if(n == 0) {
            return 0;
        }
        if(n == 1 ||n == 2) {
            return 1;
        }
        int[] dp = new int[n+1];
        dp[0] = 0;
        dp[1] = 1;
        dp[2] = 1;
        for(int i = 3; i <= n; i++) {
            dp[i] = dp[i-1] + dp[i-2] + dp[i-3];
        }
        return dp[n];
    }
}

对代码进行了空间优化:

java 复制代码
class Solution {
    public int tribonacci(int n) {
        //处理边界情况
        if(n == 0) {
            return 0;
        }
        if(n == 1 || n == 2) return 1;

        //空间优化
        int a = 0, b = 1, c = 1, d = 0;
        for(int i = 3; i <= n; i++) {
            d = a + b + c;
            a = b;
            b = c;
            c = d;
        }
        return d;
    }
}

2. 三步问题

题目链接

2.1 解题思路

2.2 代码实现

java 复制代码
class Solution {
    public int waysToStep(int n) {
        int MOD = (int)1e9 + 7;

        //处理边界条件
        if(n == 1) return 1;
        if(n == 2) return 2;
        if(n == 3) return 4;

        int[] dp = new int[n+1];
        dp[1] = 1;
        dp[2] = 2;
        dp[3] = 4;
        for(int i = 4; i <= n; i++) {
            dp[i] = ((dp[i-1] + dp[i-2]) % MOD + dp[i-3]) % MOD;
        }
        return dp[n];
    }
}

3. 使用最小花费爬楼梯

题目链接

3.1 解题思路

3.2 代码实现

思路一:

java 复制代码
class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int len = cost.length;

        int[] dp = new int[len + 1];
        dp[0] = 0;
        dp[1] = 0;
        for(int i = 2; i < len + 1; i++) {
            dp[i] = Math.min(dp[i-1] + cost[i-1],dp[i-2] + cost[i-2]);
        }
        return dp[len];
    }
}

思路二:

java 复制代码
class Solution {
    public int minCostClimbingStairs(int[] cost) {
        int n = cost.length;
        
        int[] dp = new int[n + 1];
        dp[n-1] = cost[n-1];
        dp[n-2] = cost[n-2];

        for(int i = n - 3; i >= 0; i--) {
            dp[i] = Math.min(dp[i+1] + cost[i], dp[i+2] + cost[i]);
        }
        return Math.min(dp[0], dp[1]);
    }
}

4. 解码方法

题目链接

4.1 解题思路

4.2 代码实现

java 复制代码
class Solution {
    public int numDecodings(String s) {
        char[] arr = s.toCharArray();
        int n = arr.length;
        int[] dp = new int[n];

        if(arr[0] != '0') dp[0] = 1;
        if(n == 1) return dp[0];

        if(arr[1] != '0' && arr[0] != '0') dp[1] += 1;
        int tmp = (arr[0] - '0') * 10 + (arr[1] - '0');
        if(tmp >= 10 && tmp <= 26) dp[1] += 1;

        int count = 0;
        for(int i = 2; i < n; i++) {
            if(arr[i] != '0') dp[i] += dp[i-1];

            int sum = (arr[i-1] - '0') * 10 + (arr[i] - '0');
            if(sum >= 10 && sum <= 26) dp[i] += dp[i-2];
        }
        return dp[n-1];
    }
}

我们还可以对上面代码中的初始化代码进行优化,将dp数组大小扩大一位,将初始化原来dp[1]位置的值,放在循环里面,代码如下:

java 复制代码
class Solution {
    public int numDecodings(String s) {
        char[] arr = s.toCharArray();
        int n = arr.length;
        int[] dp = new int[n + 1];

        dp[0] = 1;
        if(arr[0] != '0') dp[1] = 1;

        for(int i = 2; i <= n; i++) {
            if(arr[i - 1] != '0') dp[i] += dp[i-1];

            int sum = (arr[i - 2] - '0') * 10 + (arr[i - 1] - '0');
            if(sum >= 10 && sum <= 26) dp[i] += dp[i-2];
        }
        return dp[n];
    }
}
相关推荐
严文文-Chris2 小时前
【监督学习常用算法总结】
学习·算法
feifeigo1232 小时前
电池的荷电状态(SOC)估计
算法
博语小屋3 小时前
力扣 15.三数之和(medium)(双指针)
算法·leetcode·职场和发展
无敌最俊朗@3 小时前
双指针-力扣hot100-移动零.283
算法·leetcode·职场和发展
练习时长一年3 小时前
LeetCode热题100(腐烂的橘子)
算法·leetcode·职场和发展
Тиё Сиротака8 小时前
红包分配算法的严格数学理论与完整实现
算法
potato_may9 小时前
链式二叉树 —— 用指针构建的树形世界
c语言·数据结构·算法·链表·二叉树
java修仙传10 小时前
每日一题,力扣560. 和为 K 的子数组
算法·leetcode
ada7_10 小时前
LeetCode(python)——148.排序链表
python·算法·leetcode·链表