From 515479d66ea46912939df62968b7668230d75d29 Mon Sep 17 00:00:00 2001 From: zhangsan <646228430@qq.com> Date: Thu, 10 Apr 2025 15:53:54 +0800 Subject: [PATCH] =?UTF-8?q?4.10=20=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92?= =?UTF-8?q?=E7=AE=80=E5=8D=95=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .../java/dynamic_programming/ClimbStairs.java | 28 +++++++++++ .../java/dynamic_programming/Generate.java | 50 +++++++++++++++++++ .../MinCostClimbingStairs.java | 37 ++++++++++++++ .../java/dynamic_programming/UniquePaths.java | 37 ++++++++++++++ .../UniquePathsWithObstacles.java | 46 +++++++++++++++++ 5 files changed, 198 insertions(+) create mode 100644 src/main/java/dynamic_programming/ClimbStairs.java create mode 100644 src/main/java/dynamic_programming/Generate.java create mode 100644 src/main/java/dynamic_programming/MinCostClimbingStairs.java create mode 100644 src/main/java/dynamic_programming/UniquePaths.java create mode 100644 src/main/java/dynamic_programming/UniquePathsWithObstacles.java diff --git a/src/main/java/dynamic_programming/ClimbStairs.java b/src/main/java/dynamic_programming/ClimbStairs.java new file mode 100644 index 0000000..edfd1f1 --- /dev/null +++ b/src/main/java/dynamic_programming/ClimbStairs.java @@ -0,0 +1,28 @@ +package dynamic_programming; +/** + * 题目: 70. 爬楼梯 (climbStairs) + * 描述:假设你正在爬楼梯。需要 n 阶你才能到达楼顶。 + * 每次你可以爬 1 或 2 个台阶。你有多少种不同的方法可以爬到楼顶呢? + + 示例 2: + 输入:n = 2 + 输出:2 + 解释:有两种方法可以爬到楼顶。 + 1. 1 阶 + 1 阶 + 2. 2 阶 + + * 链接:https://leetcode.cn/problems/climbing-stairs/ + */ +public class ClimbStairs { + public int climbStairs(int n) { + if(n <= 2) return n; + int a = 1, b = 2, sum = 0; + + for(int i = 3; i <= n; i++){ + sum = a + b; // f(i - 1) + f(i - 2) + a = b; // 记录f(i - 1),即下一轮的f(i - 2) + b = sum; // 记录f(i),即下一轮的f(i - 1) + } + return b; + } +} diff --git a/src/main/java/dynamic_programming/Generate.java b/src/main/java/dynamic_programming/Generate.java new file mode 100644 index 0000000..c365721 --- /dev/null +++ b/src/main/java/dynamic_programming/Generate.java @@ -0,0 +1,50 @@ +package dynamic_programming; + +import java.util.ArrayList; +import java.util.List; + +/** + * 题目: 118. 杨辉三角 (generate) + * 描述:给定一个非负整数 numRows,生成「杨辉三角」的前 numRows 行。 + * + * 在「杨辉三角」中,每个数是它左上方和右上方的数的和。 + + 示例 2: + 输入: numRows = 5 + 输出: [[1],[1,1],[1,2,1],[1,3,3,1],[1,4,6,4,1]] + + * 链接:https://leetcode.cn/problems/pascals-triangle/ + */ +public class Generate { + public List> generate(int numRows) { + List>res=new ArrayList<>(); + Listpre = null; + for (int i = 0; i < numRows; i++) { + Listtemp=new ArrayList<>(); + for (int j = 0; j < i+1; j++) { + if(j==0||j==i) + temp.add(1); + else temp.add(pre.get(j-1)+pre.get(j)); + } + res.add(temp); + pre=new ArrayList<>(temp); + } + return res; + } + //官方题解 差不多 + public List> generate1(int numRows) { + List> ret = new ArrayList>(); + for (int i = 0; i < numRows; ++i) { + List row = new ArrayList(); + for (int j = 0; j <= i; ++j) { + if (j == 0 || j == i) { + row.add(1); + } else { + row.add(ret.get(i - 1).get(j - 1) + ret.get(i - 1).get(j)); + } + } + ret.add(row); + } + return ret; + } +} diff --git a/src/main/java/dynamic_programming/MinCostClimbingStairs.java b/src/main/java/dynamic_programming/MinCostClimbingStairs.java new file mode 100644 index 0000000..a8ebb80 --- /dev/null +++ b/src/main/java/dynamic_programming/MinCostClimbingStairs.java @@ -0,0 +1,37 @@ +package dynamic_programming; +/** + * 题目: 746. 使用最小花费爬楼梯 (MinCostClimbingStairs) + * 描述:给你一个整数数组 cost ,其中 cost[i] 是从楼梯第 i 个台阶向上爬需要支付的费用。一旦你支付此费用,即可选择向上爬一个或者两个台阶。 + * 你可以选择从下标为 0 或下标为 1 的台阶开始爬楼梯。 + * 请你计算并返回达到楼梯顶部的最低花费。 + + 示例 2: + 输入:cost = [10,15,20] + 输出:15 + 解释:你将从下标为 1 的台阶开始。 + - 支付 15 ,向上爬两个台阶,到达楼梯顶部。 + 总花费为 15 。 + + * 链接:https://leetcode.cn/problems/min-cost-climbing-stairs/ + */ +public class MinCostClimbingStairs { + public int minCostClimbingStairs(int[] cost) { + int n = cost.length; + int[] dp = new int[n + 1]; + // 默认第一步和第二步不花费体力 + dp[0] = 0; + dp[1] = 0; + // 从第 2 阶开始,递推计算到顶楼 + for (int i = 2; i <= n; i++) { + dp[i] = Math.min(dp[i - 1] + cost[i - 1], dp[i - 2] + cost[i - 2]); + } + return dp[n]; + } + + // 供测试使用的main方法 + public static void main(String[] args) { + MinCostClimbingStairs sol = new MinCostClimbingStairs(); + int[] cost = {10, 15, 20}; + System.out.println("最低花费为: " + sol.minCostClimbingStairs(cost)); + } +} diff --git a/src/main/java/dynamic_programming/UniquePaths.java b/src/main/java/dynamic_programming/UniquePaths.java new file mode 100644 index 0000000..8f9a1d9 --- /dev/null +++ b/src/main/java/dynamic_programming/UniquePaths.java @@ -0,0 +1,37 @@ +package dynamic_programming; +/** + * 题目: 62. 不同路径 (uniquePaths) + * 描述:一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。 + * 机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。 + * 问总共有多少条不同的路径? + + 示例 2: + 输入:m = 3, n = 2 + 输出:3 + 解释: + 从左上角开始,总共有 3 条路径可以到达右下角。 + 1. 向右 -> 向下 -> 向下 + 2. 向下 -> 向下 -> 向右 + 3. 向下 -> 向右 -> 向下 + + * 链接:https://leetcode.cn/problems/unique-paths/ + */ +public class UniquePaths { + public static int uniquePaths(int m, int n) { + int[][] dp = new int[m][n]; + //初始化 + for (int i = 0; i < m; i++) { //首先dp[i][0]一定都是1,因为从(0, 0)的位置到(i, 0)的路径只有一条,那么dp[0][j]也同理。 + dp[i][0] = 1; + } + for (int i = 0; i < n; i++) { + dp[0][i] = 1; + } + + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + dp[i][j] = dp[i-1][j]+dp[i][j-1]; + } + } + return dp[m-1][n-1]; + } +} diff --git a/src/main/java/dynamic_programming/UniquePathsWithObstacles.java b/src/main/java/dynamic_programming/UniquePathsWithObstacles.java new file mode 100644 index 0000000..a00330e --- /dev/null +++ b/src/main/java/dynamic_programming/UniquePathsWithObstacles.java @@ -0,0 +1,46 @@ +package dynamic_programming; +/** + * 题目: 63. 不同路径 II (uniquePathsWithObstacles) + * 描述:给定一个 m x n 的整数数组 grid。一个机器人初始位于 左上角(即 grid[0][0])。机器人尝试移动到 右下角(即 grid[m - 1][n - 1])。机器人每次只能向下或者向右移动一步。 + * 网格中的障碍物和空位置分别用 1 和 0 来表示。机器人的移动路径中不能包含 任何 有障碍物的方格。 + * 返回机器人能够到达右下角的不同路径数量。 + * 测试用例保证答案小于等于 2 * 109。 + + 示例 2: + 输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]] + 输出:2 + 解释:3x3 网格的正中间有一个障碍物。 + 从左上角到右下角一共有 2 条不同的路径: + 1. 向右 -> 向右 -> 向下 -> 向下 + 2. 向下 -> 向下 -> 向右 -> 向右 + + * 链接:https://leetcode.cn/problems/unique-paths/ + */ +public class UniquePathsWithObstacles { + public int uniquePathsWithObstacles(int[][] obstacleGrid) { + int m=obstacleGrid.length,n=obstacleGrid[0].length; + int[][]dp=new int[m][n]; + for (int i = 0; i < m; i++) { //首先dp[i][0]一定都是1,因为从(0, 0)的位置到(i, 0)的路径只有一条,那么dp[0][j]也同理。 + if(obstacleGrid[i][0]!=1) + dp[i][0] = 1; + else + break; + } + for (int i = 0; i < n; i++) { + if(obstacleGrid[0][i]!=1) + dp[0][i] = 1; + else + break; + } + for (int i = 1; i < m; i++) { + for (int j = 1; j < n; j++) { + if(obstacleGrid[i][j]==1) + dp[i][j]=0; + else + dp[i][j] = dp[i-1][j]+dp[i][j-1]; + } + } + return dp[m-1][n-1]; + } +} +