修改动态规划-背包问题第四个成能通过leetcode的代码

This commit is contained in:
FSSDAWN 2019-10-05 19:24:52 +08:00
parent 656c875d96
commit 7fe96867ee

View File

@ -57,7 +57,6 @@
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=dp[i-1]+dp[i-2]" class="mathjax-pic"/></div> <br>--> <!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=dp[i-1]+dp[i-2]" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/14fe1e71-8518-458f-a220-116003061a83.png" width="200px"> </div><br> <div align="center"> <img src="pics/14fe1e71-8518-458f-a220-116003061a83.png" width="200px"> </div><br>
考虑到 dp[i] 只与 dp[i - 1] dp[i - 2] 有关因此可以只用两个变量来存储 dp[i - 1] dp[i - 2]使得原来的 O(N) 空间复杂度优化为 O(1) 复杂度 考虑到 dp[i] 只与 dp[i - 1] dp[i - 2] 有关因此可以只用两个变量来存储 dp[i - 1] dp[i - 2]使得原来的 O(N) 空间复杂度优化为 O(1) 复杂度
```java ```java
@ -88,7 +87,6 @@ public int climbStairs(int n) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=max(dp[i-2]+nums[i],dp[i-1])" class="mathjax-pic"/></div> <br>--> <!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=max(dp[i-2]+nums[i],dp[i-1])" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg" width="350px"> </div><br> <div align="center"> <img src="pics/2de794ca-aa7b-48f3-a556-a0e2708cb976.jpg" width="350px"> </div><br>
```java ```java
public int rob(int[] nums) { public int rob(int[] nums) {
int pre2 = 0, pre1 = 0; int pre2 = 0, pre1 = 0;
@ -142,7 +140,6 @@ private int rob(int[] nums, int first, int last) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=(i-1)*dp[i-2]+(i-1)*dp[i-1]" class="mathjax-pic"/></div> <br>--> <!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=(i-1)*dp[i-2]+(i-1)*dp[i-1]" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/da1f96b9-fd4d-44ca-8925-fb14c5733388.png" width="350px"> </div><br> <div align="center"> <img src="pics/da1f96b9-fd4d-44ca-8925-fb14c5733388.png" width="350px"> </div><br>
## 5. 母牛生产 ## 5. 母牛生产
[程序员代码面试指南-P181](#) [程序员代码面试指南-P181](#)
@ -154,7 +151,6 @@ private int rob(int[] nums, int first, int last) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=dp[i-1]+dp[i-3]" class="mathjax-pic"/></div> <br>--> <!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i]=dp[i-1]+dp[i-3]" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png" width="250px"> </div><br> <div align="center"> <img src="pics/879814ee-48b5-4bcb-86f5-dcc400cb81ad.png" width="250px"> </div><br>
# 矩阵路径 # 矩阵路径
## 1. 矩阵的最小路径和 ## 1. 矩阵的最小路径和
@ -200,7 +196,6 @@ public int minPathSum(int[][] grid) {
题目描述统计从矩阵左上角到右下角的路径总数每次只能向右或者向下移动 题目描述统计从矩阵左上角到右下角的路径总数每次只能向右或者向下移动
<div align="center"> <img src="pics/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg" width=""> </div><br> <div align="center"> <img src="pics/dc82f0f3-c1d4-4ac8-90ac-d5b32a9bd75a.jpg" width=""> </div><br>
```java ```java
public int uniquePaths(int m, int n) { public int uniquePaths(int m, int n) {
int[] dp = new int[n]; int[] dp = new int[n];
@ -421,7 +416,6 @@ public int numDecodings(String s) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[n]=max\{1,dp[i]+1|S_i<S_n\&\&i<n\}" class="mathjax-pic"/></div> <br>--> <!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[n]=max\{1,dp[i]+1|S_i<S_n\&\&i<n\}" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg" width="350px"> </div><br> <div align="center"> <img src="pics/ee994da4-0fc7-443d-ac56-c08caf00a204.jpg" width="350px"> </div><br>
对于一个长度为 N 的序列最长递增子序列并不一定会以 S<sub>N</sub> 为结尾因此 dp[N] 不是序列的最长递增子序列的长度需要遍历 dp 数组找出最大值才是所要的结果max{ dp[i] | 1 <= i <= N} 即为所求 对于一个长度为 N 的序列最长递增子序列并不一定会以 S<sub>N</sub> 为结尾因此 dp[N] 不是序列的最长递增子序列的长度需要遍历 dp 数组找出最大值才是所要的结果max{ dp[i] | 1 <= i <= N} 即为所求
## 1. 最长递增子序列 ## 1. 最长递增子序列
@ -588,7 +582,6 @@ public int wiggleMaxLength(int[] nums) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i][j]=\left\{\begin{array}{rcl}dp[i-1][j-1]&&{S1_i==S2_j}\\max(dp[i-1][j],dp[i][j-1])&&{S1_i<>S2_j}\end{array}\right." class="mathjax-pic"/></div> <br>--> <!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i][j]=\left\{\begin{array}{rcl}dp[i-1][j-1]&&{S1_i==S2_j}\\max(dp[i-1][j],dp[i][j-1])&&{S1_i<>S2_j}\end{array}\right." class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg" width="450px"> </div><br> <div align="center"> <img src="pics/ecd89a22-c075-4716-8423-e0ba89230e9a.jpg" width="450px"> </div><br>
对于长度为 N 的序列 S<sub>1</sub> 和长度为 M 的序列 S<sub>2</sub>dp[N][M] 就是序列 S<sub>1</sub> 和序列 S<sub>2</sub> 的最长公共子序列长度 对于长度为 N 的序列 S<sub>1</sub> 和长度为 M 的序列 S<sub>2</sub>dp[N][M] 就是序列 S<sub>1</sub> 和序列 S<sub>2</sub> 的最长公共子序列长度
与最长递增子序列相比最长公共子序列有以下不同点 与最长递增子序列相比最长公共子序列有以下不同点
@ -628,7 +621,6 @@ public int lengthOfLCS(int[] nums1, int[] nums2) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v)" class="mathjax-pic"/></div> <br>--> <!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[i][j]=max(dp[i-1][j],dp[i-1][j-w]+v)" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/8cb2be66-3d47-41ba-b55b-319fc68940d4.png" width="400px"> </div><br> <div align="center"> <img src="pics/8cb2be66-3d47-41ba-b55b-319fc68940d4.png" width="400px"> </div><br>
```java ```java
// W 为背包总体积 // W 为背包总体积
// N 为物品数量 // N 为物品数量
@ -657,7 +649,6 @@ public int knapsack(int W, int N, int[] weights, int[] values) {
<!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[j]=max(dp[j],dp[j-w]+v)" class="mathjax-pic"/></div> <br>--> <!--<div align="center"><img src="https://latex.codecogs.com/gif.latex?dp[j]=max(dp[j],dp[j-w]+v)" class="mathjax-pic"/></div> <br>-->
<div align="center"> <img src="pics/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg" width="300px"> </div><br> <div align="center"> <img src="pics/9ae89f16-7905-4a6f-88a2-874b4cac91f4.jpg" width="300px"> </div><br>
因为 dp[j-w] 表示 dp[i-1][j-w]因此不能先求 dp[i][j-w]防止将 dp[i-1][j-w] 覆盖也就是说要先计算 dp[i][j] 再计算 dp[i][j-w]在程序实现时需要按倒序来循环求解 因为 dp[j-w] 表示 dp[i-1][j-w]因此不能先求 dp[i][j-w]防止将 dp[i-1][j-w] 覆盖也就是说要先计算 dp[i][j] 再计算 dp[i][j-w]在程序实现时需要按倒序来循环求解
```java ```java
@ -869,18 +860,17 @@ return -1.
```java ```java
public int coinChange(int[] coins, int amount) { public int coinChange(int[] coins, int amount) {
public int change(int amount, int[] coins) {
if (coins == null) {
return 0;
}
int[] dp = new int[amount + 1]; int[] dp = new int[amount + 1];
dp[0] = 1; Arrays.fill(dp, amount + 1);
for (int coin : coins) { dp[0] = 0;
for (int i = coin; i <= amount; i++) { for (int i = 1; i < dp.length; i++) {
dp[i] += dp[i - coin]; for (int j = 0; j < coins.length; j++) {
if (coins[j] <= i) {
dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
} }
} }
return dp[amount]; }
return dp[amount] > amount ? -1 : dp[amount];
} }
``` ```
@ -1004,7 +994,6 @@ public int combinationSum4(int[] nums, int target) {
<div align="center"> <img src="pics/83acbb02-872a-4178-b22a-c89c3cb60263.jpg" width="300px"> </div><br> <div align="center"> <img src="pics/83acbb02-872a-4178-b22a-c89c3cb60263.jpg" width="300px"> </div><br>
```java ```java
public int maxProfit(int[] prices) { public int maxProfit(int[] prices) {
if (prices == null || prices.length == 0) { if (prices == null || prices.length == 0) {
@ -1045,7 +1034,6 @@ The total profit is ((8 - 1) - 2) + ((9 - 4) - 2) = 8.
题目描述每交易一次都要支付一定的费用 题目描述每交易一次都要支付一定的费用
<div align="center"> <img src="pics/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png" width="300px"> </div><br> <div align="center"> <img src="pics/1e2c588c-72b7-445e-aacb-d55dc8a88c29.png" width="300px"> </div><br>
```java ```java
public int maxProfit(int[] prices, int fee) { public int maxProfit(int[] prices, int fee) {
int N = prices.length; int N = prices.length;