Skip to content

Commit f242a69

Browse files
committed
[Function add]
1. Add leetcode solutions with tag dp.
1 parent ec0725a commit f242a69

10 files changed

+477
-2
lines changed

README.md

+6
Original file line numberDiff line numberDiff line change
@@ -593,6 +593,12 @@
593593
* [712. Minimum ASCII Delete Sum for Two Strings](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/712.%20Minimum%20ASCII%20Delete%20Sum%20for%20Two%20Strings.md)
594594
* [322. Coin Change](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/322.%20Coin%20Change.md)
595595
* [377. Combination Sum IV](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/377.%20Combination%20Sum%20IV.md)
596+
* [416. Partition Equal Subset Sum](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/416.%20Partition%20Equal%20Subset%20Sum.md)
597+
* [494. Target Sum](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/494.%20Target%20Sum.md)
598+
* [813. Largest Sum of Averages](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/813.%20Largest%20Sum%20of%20Averages.md)
599+
* [312. Burst Balloons](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/312.%20Burst%20Balloons.md)
600+
* [664. Strange Printer](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/664.%20Strange%20Printer.md)
601+
* [741. Cherry Pickup](https://github.com/Seanforfun/Algorithm-and-Leetcode/blob/master/leetcode/741.%20Cherry%20Pickup.md)
596602

597603

598604
## Algorithm(4th_Edition)

leetcode/120. Triangle.md

+25-1
Original file line numberDiff line numberDiff line change
@@ -76,4 +76,28 @@ class Solution {
7676
return dp[0];
7777
}
7878
}
79-
```
79+
```
80+
81+
### Third time
82+
* Method 1: dp + rotation array
83+
```Java
84+
class Solution {
85+
public int minimumTotal(List<List<Integer>> triangle) {
86+
int height = triangle.size(), width = triangle.get(height - 1).size();
87+
int[] dp = new int[width];
88+
int temp = 0, pre = 0;
89+
for(int i = 0; i < width; i++){
90+
dp[i] = triangle.get(height - 1).get(i);
91+
}
92+
for(int i = height - 2; i >= 0; i--){
93+
temp = dp[i + 1];
94+
for(int j = i; j >= 0; j--){
95+
pre = dp[j];
96+
dp[j] = triangle.get(i).get(j) + Math.min(dp[j], temp);
97+
temp = pre;
98+
}
99+
}
100+
return dp[0];
101+
}
102+
}
103+
```

leetcode/546. Remove Boxes.md

+65
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,65 @@
1+
## 546. Remove Boxes
2+
3+
### Question
4+
Given several boxes with different colors represented by different positive numbers.
5+
You may experience several rounds to remove boxes until there is no box left. Each time you can choose some continuous boxes with the same color (composed of k boxes, k >= 1), remove them and get k*k points.
6+
Find the maximum points you can get.
7+
8+
```
9+
Example 1:
10+
Input:
11+
12+
[1, 3, 2, 2, 2, 3, 4, 3, 1]
13+
14+
Output:
15+
16+
23
17+
18+
Explanation:
19+
20+
[1, 3, 2, 2, 2, 3, 4, 3, 1]
21+
----> [1, 3, 3, 4, 3, 1] (3*3=9 points)
22+
----> [1, 3, 3, 3, 1] (1*1=1 points)
23+
----> [1, 1] (3*3=9 points)
24+
----> [] (2*2=4 points)
25+
```
26+
27+
Note: The number of boxes n would not exceed 100.
28+
29+
30+
### Solution:
31+
* Method 1: dp
32+
![Imgur](https://i.imgur.com/McRrZYK.png)
33+
* dp[i][j][k]: represents the maximum score from index i to j and k means the number of boxes[j] appended after index j.
34+
* Example [A, B, A, A, A] : dp[0][0][3] = 17 => (1 + 16)
35+
* State transfer function:
36+
* case 1: dp[i][j][k] = dp[i][j - 1][0] + (k + 1) ^ 2 -> This means we merge boxes[j] with the following boxes[j]
37+
* case 2: dp[i][j][k] = dp[i][p][k + 1] + dp[p + 1][j - 1][0] where i <= p < j && boxes[p] == boxes[j]
38+
* dp[i][p][k + 1]: since boxes[p] == boxes[j], so k + 1 means the previous k and the boxes[j].
39+
* dp[p + 1][j - 1][0]: the max score between p + 1 and j - 1.
40+
* Final result: dp[0][len - 1][0].
41+
```Java
42+
class Solution {
43+
private int[][][] dp;
44+
public int removeBoxes(int[] boxes) {
45+
int len = boxes.length;
46+
dp = new int[len][len][len];
47+
return dfs(boxes, 0, len - 1, 0);
48+
}
49+
private int dfs(int[] boxes, int i, int j, int k){
50+
if(i > j) return 0;
51+
if(dp[i][j][k] > 0) return dp[i][j][k];
52+
dp[i][j][k] = dfs(boxes, i, j - 1, 0) + (k + 1) * (k + 1);
53+
for(int p = i; p < j; p++){
54+
if(boxes[p] == boxes[j]){
55+
dp[i][j][k] = Math.max(dp[i][j][k], dfs(boxes, i, p, k + 1) + dfs(boxes, p + 1, j - 1, 0));
56+
}
57+
}
58+
return dp[i][j][k];
59+
}
60+
}
61+
```
62+
63+
64+
### Reference
65+
1. [花花酱 LeetCode 546. Remove Boxes](https://zxi.mytechroad.com/blog/dynamic-programming/leetcode-546-remove-boxes/)

leetcode/62. Unique Paths.md

+19
Original file line numberDiff line numberDiff line change
@@ -70,3 +70,22 @@ class Solution {
7070
}
7171
}
7272
```
73+
74+
### Third time
75+
* Method 1: dp[i][j]: the number of ways of reaching position (i, j);
76+
```Java
77+
class Solution {
78+
public int uniquePaths(int m, int n) {
79+
int[][] dp = new int[m][n];
80+
dp[0][0] = 1;
81+
for(int i = 1; i < m; i++) dp[i][0] = 1;
82+
for(int i = 1; i < n; i++) dp[0][i] = 1;
83+
for(int i = 1; i < m; i++){
84+
for(int j = 1; j < n; j++){
85+
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
86+
}
87+
}
88+
return dp[m - 1][n - 1];
89+
}
90+
}
91+
```

leetcode/63. Unique Paths II.md

+28
Original file line numberDiff line numberDiff line change
@@ -90,3 +90,31 @@ class Solution {
9090
}
9191
}
9292
```
93+
94+
### Thrid time
95+
* Method 1:dp
96+
```Java
97+
class Solution {
98+
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
99+
int height = obstacleGrid.length, width = obstacleGrid[0].length;
100+
int[][] dp = new int[height][width];
101+
if(obstacleGrid[0][0] == 1) return 0;
102+
dp[0][0] = 1;
103+
for(int i = 1; i < height; i++){
104+
if(obstacleGrid[i][0] == 1) break;
105+
dp[i][0] = 1;
106+
}
107+
for(int i = 1; i < width; i++){
108+
if(obstacleGrid[0][i] == 1) break;
109+
dp[0][i] = 1;
110+
}
111+
for(int i = 1; i < height; i++){
112+
for(int j = 1; j < width; j++){
113+
if(obstacleGrid[i][j] == 1) continue;
114+
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
115+
}
116+
}
117+
return dp[height - 1][width - 1];
118+
}
119+
}
120+
```

leetcode/64. Minimum Path Sum.md

+22
Original file line numberDiff line numberDiff line change
@@ -66,3 +66,25 @@ class Solution {
6666
}
6767
}
6868
```
69+
70+
### Third time
71+
* Method 1: dp
72+
```Java
73+
class Solution {
74+
public int minPathSum(int[][] grid) {
75+
int height = grid.length, width = grid[0].length;
76+
int[][] dp = new int[height][width];
77+
dp[0][0] = grid[0][0];
78+
for(int i = 1; i < height; i++)
79+
dp[i][0] = dp[i - 1][0] + grid[i][0];
80+
for(int i = 1; i < width; i++)
81+
dp[0][i] = dp[0][i - 1] + grid[0][i];
82+
for(int i = 1; i < height; i++){
83+
for(int j = 1; j < width; j++){
84+
dp[i][j] = Math.min(dp[i - 1][j], dp[i][j - 1]) + grid[i][j];
85+
}
86+
}
87+
return dp[height - 1][width - 1];
88+
}
89+
}
90+
```

leetcode/664. Strange Printer.md

+61
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
## 664. Strange Printer
2+
3+
### Question
4+
We There is a strange printer with the following two special requirements:
5+
1. The printer can only print a sequence of the same character each time.
6+
2. At each turn, the printer can print new characters starting from and ending at any places, and will cover the original existing characters.
7+
8+
Given a string consists of lower English letters only, your job is to count the minimum number of turns the printer needed in order to print it.
9+
10+
```
11+
Example 1:
12+
13+
Input: "aaabbb"
14+
Output: 2
15+
Explanation: Print "aaa" first and then print "bbb".
16+
17+
Example 2:
18+
19+
Input: "aba"
20+
Output: 2
21+
Explanation: Print "aaa" first and then print "b" from the second place of the string, which will cover the existing character 'a'.
22+
```
23+
24+
Hint: Length of the given string will not exceed 100.
25+
26+
### Solution:
27+
* Method 1: dp O(N^3)
28+
![Imgur](https://i.imgur.com/1ev7RAn.png)
29+
* the hint of 100 means the O(N^3), 500 - 1000 always means O(N^2)
30+
* how can we use the dp? We need to combine recursion and dp together.
31+
* Recursion: turn(s, i, j) get the minimum step to print s from index i to j.
32+
* fallback: turn(s, i, j) = turn(s, i, j - 1) + 1;
33+
* Optimization: dp[i][j] = dp[i][k] + dp[k + 1][j - 1] where k >= i && k < j and we need char at k euqals char at j.
34+
* since charAt(k) == charAt(j), we can print their value as that char duing the period of dp[i][k].
35+
```Java
36+
class Solution {
37+
private int[][] dp;
38+
public int strangePrinter(String s) {
39+
int len = s.length();
40+
dp = new int[len + 1][len + 1];
41+
return turn(s, 1, len);
42+
}
43+
private int turn(String s, int i, int j){
44+
if(i > j) return 0; //empty string.
45+
else if(dp[i][j] > 0) return dp[i][j]; //Cached
46+
else{
47+
//Give the fall back.
48+
dp[i][j] = turn(s, i, j - 1) + 1;
49+
for(int k = i; k < j; k++){
50+
if(s.charAt(j - 1) == s.charAt(k - 1))
51+
dp[i][j] = Math.min(turn(s, i, k) + turn(s, k + 1, j - 1), dp[i][j]);
52+
}
53+
return dp[i][j];
54+
}
55+
}
56+
}
57+
```
58+
59+
60+
### Reference
61+
1. [花花酱 LeetCode 664. Strange Printer](http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-664-strange-printer/)

leetcode/741. Cherry Pickup.md

+81
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
## 741. Cherry Pickup
2+
3+
### Question
4+
In a N x N grid representing a field of cherries, each cell is one of three possible integers.
5+
* 0 means the cell is empty, so you can pass through;
6+
* 1 means the cell contains a cherry, that you can pick up and pass through;
7+
* -1 means the cell contains a thorn that blocks your way.
8+
9+
10+
11+
Your task is to collect maximum number of cherries possible by following the rules below:
12+
* Starting at the position (0, 0) and reaching (N-1, N-1) by moving right or down through valid path cells (cells with value 0 or 1);
13+
* After reaching (N-1, N-1), returning to (0, 0) by moving left or up through valid path cells;
14+
* When passing through a path cell containing a cherry, you pick it up and the cell becomes an empty cell (0);
15+
* If there is no valid path between (0, 0) and (N-1, N-1), then no cherries can be collected.
16+
17+
```
18+
Example 1:
19+
20+
Input: grid =
21+
[[0, 1, -1],
22+
[1, 0, -1],
23+
[1, 1, 1]]
24+
Output: 5
25+
Explanation:
26+
The player started at (0, 0) and went down, down, right right to reach (2, 2).
27+
4 cherries were picked up during this single trip, and the matrix becomes [[0,1,-1],[0,0,-1],[0,0,0]].
28+
Then, the player went left, up, up, left to return home, picking up one more cherry.
29+
The total number of cherries picked up is 5, and this is the maximum possible.
30+
```
31+
32+
Note:
33+
1. grid is an N by N 2D array, with 1 <= N <= 50.
34+
2. Each grid[i][j] is an integer in the set {-1, 0, 1}.
35+
3. It is guaranteed that grid[0][0] and grid[N-1][N-1] are not -1.
36+
37+
### Solution:
38+
* Method 1: dp
39+
![Imgur](https://i.imgur.com/Qm9Ymed.png)
40+
* dp[x1][y1][x2]: the max cherry can pick up to (x1, y1), (x2, y2) where y2 = x1 + y1 - x2. This dp means we have 2 people picking cherry from (0, 0) to (N - 1, N - 1).
41+
* dp[x1][y1][x2] = max(dp(x1 - 1, y1, x2), dp(x1, y1 - 1, x2), dp(x1 - 1, y1, x2 - 1), dp(x1, y1 - 1, x2 - 1)) + grid[x1][y1] + grid[x2][y2].
42+
* if both at same position, and current value is 1, only increase once.
43+
```Java
44+
class Solution {
45+
private int[][][] dp;
46+
public int cherryPickup(int[][] grid) {
47+
int height = grid.length, width = grid[0].length;
48+
dp = new int[height][width][height];
49+
for(int i = 0; i < height; i++)
50+
for(int j = 0; j < width; j++)
51+
Arrays.fill(dp[i][j], Integer.MIN_VALUE);
52+
return Math.max(dp(grid, height - 1, width - 1, height - 1), 0);
53+
}
54+
private int dp(int[][] grid, int x1, int y1, int x2){
55+
int y2 = x1 + y1 - x2;
56+
if(x1 < 0 || y1 < 0 || x2 < 0 || y2 < 0){
57+
return -1;
58+
}
59+
if(x1 == 0 && y1 == 0 && x2 == 0){
60+
dp[0][0][0] = grid[0][0];
61+
return dp[0][0][0];
62+
}
63+
if(dp[x1][y1][x2] != Integer.MIN_VALUE) return dp[x1][y1][x2];
64+
if(grid[x1][y1] == -1 || grid[x2][y2] == -1) return -1;
65+
dp[x1][y1][x2] = Math.max(Math.max(dp(grid, x1 - 1, y1, x2), dp(grid, x1, y1 - 1, x2)),
66+
Math.max(dp(grid, x1, y1 - 1, x2 - 1), dp(grid, x1 - 1, y1, x2 - 1)));
67+
if(dp[x1][y1][x2] >= 0){
68+
int g1 = grid[x1][y1], g2 = grid[x2][y2];
69+
if(g1 >= 0) dp[x1][y1][x2] += g1;
70+
if(g2 >= 0) dp[x1][y1][x2] += g2;
71+
if(g1 == g2 && g1 == 1 && x1 == x2 && y1 == y2)
72+
dp[x1][y1][x2]--;
73+
}
74+
return dp[x1][y1][x2];
75+
}
76+
}
77+
```
78+
79+
80+
### Reference
81+
1. [花花酱 LeetCode 741. Cherry Pickup](http://zxi.mytechroad.com/blog/dynamic-programming/leetcode-741-cherry-pickup/)

0 commit comments

Comments
 (0)