LeetCode之动态规划

1、爬楼梯

1.1 题目

1.2 题解

1.3 代码

1.3.1 递归

递归更容易相当和理解,但leetcode会超时

java 复制代码
class Solution {

    // 思路:基于递归实现,第n级的次数,等于第n-1和第n-2级次数之和
    public int climbStairs(int n) {
        // 第1级有1种方法
        if (n == 1) {
            return 1;
        }
        // 第2级有2种方法
        if (n == 2) {
            return 2;
        }
        // 第n级就是n-1级的方法 + n-2级的方法
        return climbStairs(n-1) + climbStairs(n-2);
    }
    
}

1.3.2 动态规划

思路:

动态规划,数组存储每个台阶的方法

遍历数组,i - 1加i - 2即是当前台阶的方法,全部存到相应的数组

最后result[n]就是n级台阶的方法

java 复制代码
class Solution {

    // 思路:基于动态规划
    public int climbStairs(int n) {
        // 处理边界条件
        if (n == 1) {
            return 1;
        }
        // 用数组记录n个台阶的方法数,其中跳过了索引0
        int[] result = new int[n + 1];
        // 台阶数为1是1种方法
        result[1] = 1;
        // 台阶数为2是2种方法
        result[2] = 2;

        // 台阶数为3时遍历到最后
        for (int i = 3; i <= n; i++) {
            // 那i阶就等于i-1 加 i-2时的和
            result[i] = result[i - 1] + result[i -2];
        }
        // 最后返回n阶台阶即是结果
        return result[n];
    }
}

2、杨辉三角

2.1 题目

2.2 题解

2.3 代码

Dynamic programming

dp:

定义状态 dpi][j] 为杨辉三角中第 i 行第 j 列(行列索引从 0 开始)的元素值。

状态转移方程为:dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j],其中 dp[i - 1][j - 1] 和 dp[i - 1][j] 是当前元素左上方和上方的元素值。

需要注意的是,每一行的第一个元素和最后一个元素都是 1,即当 j=0 或 j=i 时,dp[i][j] = 1。

java 复制代码
class Solution {

    // 思路:基于动态规划,
    // 状态转移方程 dp[i][j] = dp[i-1]dp[j-1] + dp[i-1]dp[j]
    // 每一行的第一个和最后一个元素都是1
    public List<List<Integer>> generate(int numRows) {
        // 初始化动态规划数组,一行数组长度就是1
        Integer[][] dp = new Integer[numRows][];

        // 遍历每一行
        for (int i = 0; i < numRows; i++) {
            // 初始化当前行,因为从0开始的,所以当前行数组长度应为 i + 1
            dp[i] = new Integer[i  + 1];
            // 每一行的第一个元素为1
            dp[i][0] = 1;
            // 每一行的最后一个元素为1 array.length -1 = (i + 1) - 1
            dp[i][i] = 1;
            // 计算中间元素(取出收尾都是1)
            for (int j = 1; j < i; j++) {
                // 套用公式中间元素等于上一行的相邻两个元素之和
                dp[i][j] = dp[i - 1][j - 1] + dp[i - 1][j];
            }
        }

        // 将动态规划数组转换为结果列表
        List<List<Integer>> result = new ArrayList<>();
        for (Integer[] nums : dp) {
            result.add(Arrays.asList(nums));
        }
        // 返回结果列表
        return result;
    }

}

3、打家劫舍

3.1 题目

3.2 题解

3.3 代码

基于动态规划,如果房子为1,直接偷了就算了

如果房子为2,那的看下哪一个大偷了就是了

如果大于2,如果第i个房子要偷,最大值就是前i-2加上i的和,否则不偷就是

第i-1个的和,就有公式了 dp[i] = Math.max((dp[i-2] + nums[i]), dp[i-1])

java 复制代码
class Solution {

    public int rob(int[] nums) {
        // 思路:动态规划
        // 处理边界,为空直接是0
        if (nums == null ||nums.length == 0) {
            return 0;
        }
        // 如果房子为1,直接偷了就是了
        if (nums.length == 1) {
            return nums[0];
        }
        // 如果房子为2,那得看看哪一个多偷了就是了
        if (nums.length == 2) {
            return Math.max(nums[0], nums[1]);
        }
        // 构造动态规划数组
        int[] dp = new int[nums.length];
        // 赋初始值
        dp[0] = nums[0];
        dp[1] = Math.max(nums[0], nums[1]);
        // 如果房子大于2,就有公式了 dp[i] = Math.max((dp[i-2] + nums[i]), dp[i-1])
        for (int i = 2; i < nums.length; i++) {
            dp[i] = Math.max((dp[i - 2] + nums[i]), dp[i - 1]);
        }
        // 最后返回数组最后的位置
        return dp[nums.length - 1];
    }

}

4、完全平方数​​​​​​​

4.1 题目

4.2 题解

4.3 代码

java 复制代码
class Solution {
    public int numSquares(int n) {
        // 定义一个动态规划数组 n = 13 = 9 + 4
        int[] dp = new int[n + 1];
        for (int i = 1; i <= n; i++) {
            int minn = Integer.MAX_VALUE;
            for (int j = 1; j * j <= i; j++) {
                // 使用 j*j作为完全平方数的一部分,查找剩余 i-j*j的数量
                minn = Math.min(minn, dp[i - j * j]);
            }
            // 将minn + 1赋值给dp[i],加1表示使用了一个j*j平方
            dp[i] = minn + 1;
            System.out.println(dp[i]);
        }
        // 最后返回dp[n]
        return dp[n];

    }
}
相关推荐
地平线开发者2 分钟前
征程 6 工具链性能分析与优化 2|模型性能优化建议
算法·自动驾驶
Duck Bro4 分钟前
数据结构:顺序表(动态顺序表)
c语言·数据结构·c++·学习·算法
DK2215140 分钟前
机器学习系列-----主成分分析(PCA)
人工智能·算法·机器学习
oliveira-time1 小时前
爬虫学习8
开发语言·javascript·爬虫·python·算法
点云侠2 小时前
二维椭圆拟合算法及推导过程
开发语言·c++·算法·计算机视觉·matlab
一直学习永不止步2 小时前
LeetCode题练习与总结:迷你语法分析器--385
java·数据结构·算法·leetcode·字符串··深度优先搜索
Dragonlongbo2 小时前
leetcode01 --- 环形链表判定
算法·leetcode·职场和发展
-cc- Lynn2 小时前
链表类算法【leetcode】
算法·leetcode·链表
顾京2 小时前
基于扩散模型的表单插补
人工智能·深度学习·算法
小冉在学习2 小时前
day55 图论章节刷题Part07([53.寻宝]prim算法、kruskal算法)
java·算法·图论