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];

    }
}
相关推荐
会员源码网43 分钟前
使用`mysql_*`废弃函数(PHP7+完全移除,导致代码无法运行)
后端·算法
木心月转码ing2 小时前
Hot100-Day10-T438T438找到字符串中所有字母异位词
算法
HelloReader2 小时前
Wi-Fi CSI 感知技术用无线信号“看见“室内的人
算法
颜酱5 小时前
二叉树分解问题思路解题模式
javascript·后端·算法
qianpeng8976 小时前
水声匹配场定位原理及实验
算法
董董灿是个攻城狮18 小时前
AI视觉连载8:传统 CV 之边缘检测
算法
AI软著研究员1 天前
程序员必看:软著不是“面子工程”,是代码的“法律保险”
算法
FunnySaltyFish1 天前
什么?Compose 把 GapBuffer 换成了 LinkBuffer?
算法·kotlin·android jetpack
颜酱1 天前
理解二叉树最近公共祖先(LCA):从基础到变种解析
javascript·后端·算法
地平线开发者2 天前
SparseDrive 模型导出与性能优化实战
算法·自动驾驶