● 62.不同路径
1.思路
This Java code aims to solve the unique paths problem using dynamic programming. Here’s a step-by-step explanation of the code:
Initialize the 2D array: int[][] res = new int[m][n]; creates a 2D array to store the number of unique paths at each point on the grid.
Initialize the first row and column: Loop through the first row res[0][i] and the first column res[i][0] and set each cell to 1. This is because there is only one way to reach any cell in the first row or column – by moving either horizontally or vertically.
Calculate unique paths for each cell: Use a nested loop to iterate through the remaining cells (i from 1 to m-1 and j from 1 to n-1). The number of unique paths to reach the current cell (i, j) is the sum of the paths from the cell above (i-1, j) and the cell to the left (i, j-1).
Return the result: The final result is stored in the bottom-right cell of the matrix, which is res[m-1][n-1]. This represents the total number of unique paths to reach the bottom-right cell of an m x n grid.
2.代码实现
class Solution {
public int uniquePaths(int m, int n) {
int[][] res=new int[m][n];
for(int i=0;i<n;i++)
res[0][i]=1;
for(int i=0;i<m;i++)
res[i][0]=1;
for(int i=1;i<m;i++){
for(int j=1;j<n;j++){
res[i][j]=res[i][j-1]+res[i-1][j];
}
}
return res[m-1][n-1];
}
}
● 63. 不同路径 II
1.思路
Initialization: The code starts by initializing the variables m and n with the dimensions of the input grid obstacleGrid, and a 2D array res to store the number of unique paths at each point on the grid
Initialize the first row and column: Similar to the previous problem, the code initializes the first row and column of the res array. However, this time it takes into account obstacles in the input grid. The loop continues as long as there are no obstacles (obstacleGrid[0][i] == 0 or obstacleGrid[i][0] == 0).
Calculate unique paths for each cell: The code then uses a nested loop to iterate through the remaining cells (i from 1 to m-1 and j from 1 to n-1). If there is no obstacle at the current cell (obstacleGrid[i][j] == 0), it calculates the number of unique paths to reach the current cell by summing the paths from the cell above and the cell to the left.
Return the result: The final result is stored in the bottom-right cell of the matrix, which is res[m-1][n-1]. This represents the total number of unique paths to reach the bottom-right cell of the grid, considering obstacles.
2.代码实现
class Solution {
public int uniquePathsWithObstacles(int[][] obstacleGrid) {
int m=obstacleGrid.length;
int n=obstacleGrid[0].length;
int[][] res=new int[m][n];
for(int i=0;i<n&&obstacleGrid[0][i]==0;i++)
res[0][i]=1;
for(int i=0;i<m&&obstacleGrid[i][0]==0;i++)
res[i][0]=1;
for(int i=1;i<m;i++)
for(int j=1;j<n;j++){
if(obstacleGrid[i][j]==0)
res[i][j]=res[i-1][j]+res[i][j-1];
}
return res[m-1][n-1];
}
}
● 343. 整数拆分
1.思路
主要较难理解的是dp数组的初始化,以及res[i]=Math.max(Math.max(j*(i-j),j*res[i-j]),res[i]);为什么最大值比较还要取res[i]。
在程序执行的过程中,每一次j++的时候dp【i】存取的都是上一次的j留下来的dp【i】的最大值。因为在i确定的条件下,j依次递增取得的乘积最大值有可能变大有可能变小,我们取的是最大的一个,所以用右边的dp【i】保存了程序执行过程中的最大值
Dynamic Programming Array (res): The code uses a dynamic programming approach to store the maximum products in an array res. The array is of size n+1 to handle integers from 2 to n.
Base Case (res[2] = 1): The base case initializes the result for breaking the integer 2, which is set to 1.
Nested Loops: The outer loop (for (int i = 3; i <= n; i++)) iterates over integers from 3 to n, representing the integers being considered for breaking.
The inner loop (for (int j = 1; j < i; j++)) iterates over integers from 1 to i-1, representing the possible breaking points.
Update Maximum Product (res[i]): For each combination of breaking points, the code calculates three possible products:
j * (i - j): Breaking at j and (i - j)
j * res[i - j]: Breaking at j and considering the maximum product for (i - j)
res[i]: The current maximum product for i
The maximum of these three values is stored in res[i].
Final Result: The final result is the maximum product obtained by breaking the integer n, which is stored in res[n].
In summary, the algorithm uses dynamic programming to iteratively calculate the maximum product for breaking integers from 2 to n, considering all possible breaking points. The result is stored in the res array, and the final maximum product for breaking the integer n is returned.
2.代码实现
class Solution {
public int integerBreak(int n) {
//d[n]拆分数字n得到的乘积最大值
int[] res=new int[n+1];
res[2]=1;
for(int i=3;i<=n;i++){
for(int j=1;j<i;j++){
res[i]=Math.max(Math.max(j*(i-j),j*res[i-j]),res[i]);
}
}
return res[n];
}
}
● 96.不同的二叉搜索树
1.思路
dp[n] is an array where dp[i] represents the number of unique BSTs with i nodes.
The base case is initialized as dp[0] = 1 because there is only one unique BST with 0 nodes (an empty tree).
The outer loop (for (int i = 1; i <= n; i++)) iterates through each number of nodes from 1 to n.
The inner loop (for (int j = 1; j <= i; j++)) iterates through all possible roots for the current number of nodes (i).
The formula dp[i] += dp[j - 1] * dp[i - j]; calculates the total number of unique BSTs for the current number of nodes (i) by summing up the products of the number of BSTs on the left and right subtrees for each possible root (j).
The final result is stored in dp[n], representing the number of unique BSTs with n nodes.
The dynamic programming approach is used here to avoid redundant calculations and optimize the solution. The time complexity of the algorithm is O(n^2), where n is the number of nodes.
2.代码实现
class Solution {
public int numTrees(int n) {
// dp[n]: Number of unique BSTs with n nodes
int[] dp = new int[n + 1];
// Base case: There is one unique BST with 0 nodes.
dp[0] = 1;
// Iterate through each number of nodes from 1 to n.
for (int i = 1; i <= n; i++) {
// Iterate through all possible roots (j) for the current i nodes.
for (int j = 1; j <= i; j++) {
// For each root j, the total number of BSTs is the product of
// the number of BSTs on its left subtree (dp[j-1]) and the number
// of BSTs on its right subtree (dp[i-j]).
dp[i] += dp[j - 1] * dp[i - j];
}
}
// The final result is stored in dp[n], representing the number of
// unique BSTs with n nodes.
return dp[n];
}
}
● 123.买卖股票的最佳时机III
1.思路
Explanation:
The algorithm uses a dynamic programming approach to compute the maximum profit for each day based on four states.
The states represent whether the algorithm holds or does not hold the first and second stocks.
The initialization sets the states for the first day based on buying the first stock.
The loop iterates over the remaining days, updating the states based on the maximum profit in each case.
The final result is the maximum profit, considering either not holding the first or the second stock on the last day.
The time complexity of this dynamic programming solution is O(n), where n is the length of the prices array.
其实return可以写成d[len-1][3],因为d[len-1][3]包含了d[len-1][1]
2.代码实现
class Solution {
public int maxProfit(int[] prices) {
// Define four states for each day:
// 0: Holding the first stock
// 1: Not holding the first stock
// 2: Holding the second stock
// 3: Not holding the second stock
int len = prices.length;
int[][] d = new int[len][4];
// Initialize the first day's states based on buying the first stock
d[0][0] -= prices[0];
d[0][1] = 0;
d[0][2] -= prices[0];
d[0][3] = 0;
// Iterate over the remaining days
for (int i = 1; i < len; i++) {
// Calculate the state of holding the first stock on the ith day
d[i][0] = Math.max(d[i-1][0], 0 - prices[i]);
// Calculate the state of not holding the first stock on the ith day
d[i][1] = Math.max(d[i-1][1], d[i-1][0] + prices[i]);
// Calculate the state of holding the second stock on the ith day
d[i][2] = Math.max(d[i-1][2], d[i-1][1] - prices[i]);
// Calculate the state of not holding the second stock on the ith day
d[i][3] = Math.max(d[i-1][3], d[i-1][2] + prices[i]);
}
// Return the maximum profit, considering either not holding the first or the second stock
return Math.max(d[len-1][1], d[len-1][3]);
}
}
● 模板
1.思路
2.代码实现
● 模板
1.思路
2.代码实现