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

    }
}
相关推荐
小刘|21 分钟前
《Java 实现希尔排序:原理剖析与代码详解》
java·算法·排序算法
jjyangyou26 分钟前
物联网核心安全系列——物联网安全需求
物联网·算法·安全·嵌入式·产品经理·硬件·产品设计
van叶~42 分钟前
算法妙妙屋-------1.递归的深邃回响:二叉树的奇妙剪枝
c++·算法
简简单单做算法43 分钟前
基于Retinex算法的图像去雾matlab仿真
算法·matlab·图像去雾·retinex
云卓SKYDROID1 小时前
除草机器人算法以及技术详解!
算法·机器人·科普·高科技·云卓科技·算法技术
半盏茶香1 小时前
【C语言】分支和循环详解(下)猜数字游戏
c语言·开发语言·c++·算法·游戏
徐子童1 小时前
双指针算法习题解答
算法
想要打 Acm 的小周同学呀2 小时前
LRU缓存算法
java·算法·缓存
劲夫学编程3 小时前
leetcode:杨辉三角
算法·leetcode·职场和发展
毕竟秋山澪3 小时前
孤岛的总面积(Dfs C#
算法·深度优先