From 571ddaa69d9ea4bd80dcad2b70ffc25ce84f78ae Mon Sep 17 00:00:00 2001 From: yangzhaoMP Date: Wed, 6 Mar 2024 11:41:56 +0800 Subject: [PATCH 1/5] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=20?= =?UTF-8?q?=E7=88=AC=E6=A5=BC=E6=A2=AF=E6=9C=80=E5=B0=8F=E8=B4=B9=E7=8E=87?= =?UTF-8?q?=20java=20=E7=8A=B6=E6=80=81=E5=8E=8B=E7=BC=A9=E4=BC=98?= =?UTF-8?q?=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0746.使用最小花费爬楼梯.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/problems/0746.使用最小花费爬楼梯.md b/problems/0746.使用最小花费爬楼梯.md index d13ff19f..6320ed89 100644 --- a/problems/0746.使用最小花费爬楼梯.md +++ b/problems/0746.使用最小花费爬楼梯.md @@ -244,6 +244,24 @@ class Solution { } ``` +```Java +// 状态压缩,使用三个变量来代替数组 +class Solution { + public int minCostClimbingStairs(int[] cost) { + // 以下三个变量分别表示前两个台阶的最少费用、前一个的、当前的。 + int beforeTwoCost = 0, beforeOneCost = 0, currentCost = 0; + // 前两个台阶不需要费用就能上到,因此从下标2开始;因为最后一个台阶需要跨越,所以需要遍历到cost.length + for (int i = 2; i <= cost.length; i ++) { + // 此处遍历的是cost[i - 1],不会越界 + currentCost = Math.min(beforeOneCost + cost[i - 1], beforeTwoCost + cost[i - 2]); + beforeTwoCost = beforeOneCost; + beforeOneCost = currentCost; + } + return currentCost; + } +} +``` + ### Python 动态规划(版本一) From 86ff0f2a35549d75d45ae873394514e812ab8436 Mon Sep 17 00:00:00 2001 From: yangzhaoMP Date: Wed, 6 Mar 2024 11:54:19 +0800 Subject: [PATCH 2/5] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=20?= =?UTF-8?q?=E4=B8=8D=E5=90=8C=E8=B7=AF=E5=BE=84=20java=20=E7=8A=B6?= =?UTF-8?q?=E6=80=81=E5=8E=8B=E7=BC=A9=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0062.不同路径.md | 18 ++++++++++++++++++ 1 file changed, 18 insertions(+) diff --git a/problems/0062.不同路径.md b/problems/0062.不同路径.md index 207a66ee..32c64a12 100644 --- a/problems/0062.不同路径.md +++ b/problems/0062.不同路径.md @@ -285,6 +285,24 @@ public: } ``` +状态压缩 +```java +class Solution { + public int uniquePaths(int m, int n) { + // 在二维dp数组中,当前值的计算只依赖正上方和正左方,因此可以压缩成一维数组。 + int[] dp = new int[n]; + // 初始化,第一行只能从正左方跳过来,所以只有一条路径。 + Arrays.fill(dp, 1); + for (int i = 1; i < m; i ++) { + // 第一列也只有一条路,不用迭代,所以从第二列开始 + for (int j = 1; j < n; j ++) { + dp[j] += dp[j - 1]; // dp[j] = dp[j] (正上方)+ dp[j - 1] (正左方) + } + } + return dp[n - 1]; + } +} +``` ### Python 递归 From 9932bebde8bb219d3a63b1c3e5881e4c72efa9ad Mon Sep 17 00:00:00 2001 From: yangzhaoMP Date: Wed, 6 Mar 2024 12:56:20 +0800 Subject: [PATCH 3/5] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=20?= =?UTF-8?q?=E4=B9=B0=E5=8D=96=E8=82=A1=E7=A5=A8=20java=20=E6=A0=BC?= =?UTF-8?q?=E5=BC=8F=E9=97=AE=E9=A2=98?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0121.买卖股票的最佳时机.md | 3 --- 1 file changed, 3 deletions(-) diff --git a/problems/0121.买卖股票的最佳时机.md b/problems/0121.买卖股票的最佳时机.md index cbdf40e8..dafdbbed 100644 --- a/problems/0121.买卖股票的最佳时机.md +++ b/problems/0121.买卖股票的最佳时机.md @@ -287,9 +287,6 @@ class Solution { return dp[1]; } } -``` -```Java - ``` ### Python: From 1474a28a53ffe259d61aefcc822fa7e3e4959d44 Mon Sep 17 00:00:00 2001 From: yangzhaoMP Date: Wed, 6 Mar 2024 14:59:28 +0800 Subject: [PATCH 4/5] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=20?= =?UTF-8?q?=E6=9C=80=E9=95=BF=E8=BF=9E=E7=BB=AD=E9=80=92=E5=A2=9E=E5=BA=8F?= =?UTF-8?q?=E5=88=97=20java=20=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92?= =?UTF-8?q?=E7=8A=B6=E6=80=81=E5=8E=8B=E7=BC=A9=E4=BC=98=E5=8C=96?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0674.最长连续递增序列.md | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/problems/0674.最长连续递增序列.md b/problems/0674.最长连续递增序列.md index 485e321c..14a5e895 100644 --- a/problems/0674.最长连续递增序列.md +++ b/problems/0674.最长连续递增序列.md @@ -186,7 +186,23 @@ public: return res; } ``` - +> 动态规划状态压缩 +```java +class Solution { + public int findLengthOfLCIS(int[] nums) { + // 记录以 前一个元素结尾的最长连续递增序列的长度 和 以当前 结尾的...... + int beforeOneMaxLen = 1, currentMaxLen = 0; + // res 赋最小值返回的最小值1 + int res = 1; + for (int i = 1; i < nums.length; i ++) { + currentMaxLen = nums[i] > nums[i - 1] ? beforeOneMaxLen + 1 : 1; + beforeOneMaxLen = currentMaxLen; + res = Math.max(res, currentMaxLen); + } + return res; + } +} +``` > 贪心法: ```Java From 58595806a0d8fec2c810231bfa96951784add6f0 Mon Sep 17 00:00:00 2001 From: yangzhaoMP Date: Wed, 6 Mar 2024 16:03:39 +0800 Subject: [PATCH 5/5] =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=20?= =?UTF-8?q?=E5=88=A4=E6=96=AD=E5=AD=90=E5=BA=8F=E5=88=97=20java=20?= =?UTF-8?q?=E5=8A=A8=E6=80=81=E8=A7=84=E5=88=92=E7=8A=B6=E6=80=81=E5=8E=8B?= =?UTF-8?q?=E7=BC=A9?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- problems/0392.判断子序列.md | 57 ++++++++++++++++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/problems/0392.判断子序列.md b/problems/0392.判断子序列.md index ebd567cb..caca8cb8 100644 --- a/problems/0392.判断子序列.md +++ b/problems/0392.判断子序列.md @@ -173,6 +173,63 @@ class Solution { } } ``` +> 修改遍历顺序后,可以利用滚动数组,对dp数组进行压缩 +```java +class Solution { + public boolean isSubsequence(String s, String t) { + // 修改遍历顺序,外圈遍历t,内圈遍历s。使得dp的推算只依赖正上方和左上方,方便压缩。 + int[][] dp = new int[t.length() + 1][s.length() + 1]; + for (int i = 1; i < dp.length; i++) { // 遍历t字符串 + for (int j = 1; j < dp[i].length; j++) { // 遍历s字符串 + if (t.charAt(i - 1) == s.charAt(j - 1)) { + dp[i][j] = dp[i - 1][j - 1] + 1; + } else { + dp[i][j] = dp[i - 1][j]; + } + } + System.out.println(Arrays.toString(dp[i])); + } + return dp[t.length()][s.length()] == s.length(); + } +} +``` +> 状态压缩 +```java +class Solution { + public boolean isSubsequence(String s, String t) { + int[] dp = new int[s.length() + 1]; + for (int i = 0; i < t.length(); i ++) { + // 需要使用上一轮的dp[j - 1],所以使用倒序遍历 + for (int j = dp.length - 1; j > 0; j --) { + // i遍历的是t字符串,j遍历的是dp数组,dp数组的长度比s的大1,因此需要减1。 + if (t.charAt(i) == s.charAt(j - 1)) { + dp[j] = dp[j - 1] + 1; + } + } + } + return dp[s.length()] == s.length(); + } +} +``` +> 将dp定义为boolean类型,dp[i]直接表示s.substring(0, i)是否为t的子序列 + +```java +class Solution { + public boolean isSubsequence(String s, String t) { + boolean[] dp = new boolean[s.length() + 1]; + // 表示 “” 是t的子序列 + dp[0] = true; + for (int i = 0; i < t.length(); i ++) { + for (int j = dp.length - 1; j > 0; j --) { + if (t.charAt(i) == s.charAt(j - 1)) { + dp[j] = dp[j - 1]; + } + } + } + return dp[dp.length - 1]; + } +} +``` ### Python: