mirror of
https://github.com/youngyangyang04/leetcode-master.git
synced 2025-07-06 23:28:29 +08:00
@ -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
|
||||
递归
|
||||
|
@ -287,9 +287,6 @@ class Solution {
|
||||
return dp[1];
|
||||
}
|
||||
}
|
||||
```
|
||||
```Java
|
||||
|
||||
```
|
||||
|
||||
### Python:
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
|
||||
|
@ -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
|
||||
|
||||
动态规划(版本一)
|
||||
|
Reference in New Issue
Block a user