Skip to content

Commit 830ad51

Browse files
committed
动态规划注释完善
1 parent ba8d641 commit 830ad51

22 files changed

+113
-75
lines changed

leetcode_Java/Solution0022.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,8 +40,10 @@ private void dfs(String track, int n, int left, int right) {
4040
2、题目:数字n代表生成括号的对数,请你设计一个函数,用于能够生成所有可能的并且有效的括号组合。
4141
3、题目简化:求n对括号的所有有效组合
4242
4、定义dp列表:dp[i]表示i对括号的所有有效组合。本题不能用一维或二维数组,而是用二维列表,存放的是字符串对象
43-
5、状态转移方程:dp[i] = "(" + dp[p]的组合 + ")" + dp[q]的组合,其中1+p+q=i,p从0遍历到i-1,q则相应从i-1到0
44-
6、初始化:dp[0]=[""], dp[1]=["()"]
43+
5、初始化:
44+
1)一维dp数组扩容:增加0对括号这一最小规模的情况
45+
2)dp[0]=[""], dp[1]=["()"]
46+
6、状态转移方程:dp[i] = "(" + dp[p]的组合 + ")" + dp[q]的组合,其中1+p+q=i,p从0遍历到i-1,q则相应从i-1到0
4547
7、遍历dp数组填表:从前向后,第一个for循环用于遍历dp列表未知位置,第二个for循环用于遍历dp列表已知位置,得到已知结果后根据状态转移方程推断计算未知结果并填表
4648
8、返回结果:最后一个状态就是结果
4749
*/

leetcode_Java/Solution0042.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,10 +62,12 @@ private int getMax(int[] height, int start, int end) {
6262
逐列累加雨水,动态规划,时间复杂度优化,空间换时间:
6363
1、为避免重复遍历计算某位置的左右最高柱子,使用dp数组存放最高柱子
6464
2、定义dp数组:dpLeft[i]表示i位置左边最高柱子的高度,dpRight[i]表示i位置右边最高柱子的高度
65-
3、状态转移方程:
65+
3、初始化:
66+
1)一维dp数组不用扩容
67+
2)dp[0]=0,不用赋值了
68+
4、状态转移方程:
6669
dpLeft[i] = Math.max(dpLeft[i - 1], height[i - 1]);
6770
dpRight[i] = Math.max(dpRight[i + 1], height[i + 1]);
68-
4、初始化:dp[0]=0,不用赋值了
6971
4、遍历dp数组填表:一个for循环遍历dp数组填表,求 左边最高柱子的高度 则 从左往右 遍历,求 右边最高柱子的高度 则 从右往左 遍历
7072
*/
7173
class Solution {

leetcode_Java/Solution0053.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -46,8 +46,10 @@ public int maxSubArray(int[] nums) {
4646
1、题目:给你一个整数数组 nums,请你找出一个具有最大和的连续子数组(子数组最少包含一个元素),返回其最大和。子数组是数组中的一个连续部分。
4747
2、题目简化:求数组nums的具有最大和的连续子数组的和。要先求多个局部连续子数组的最大和,再从多个局部最大中得到全局最大
4848
3、定义dp数组:dp[i]表示以索引i结尾的连续子数组的最大和
49-
4、状态转移方程:dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]);
50-
5、初始化:dp[0] = nums[0];
49+
4、初始化:
50+
1)一维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化
51+
2)dp[0] = nums[0];
52+
5、状态转移方程:dp[i] = Math.max(nums[i], nums[i] + dp[i - 1]);
5153
6、遍历dp数组填表:一个for循环遍历dp数组,根据状态转移方程推断计算未知结果并填表
5254
7、返回结果:dp数组的最大值就是具有最大和的连续子数组的和
5355
*/

leetcode_Java/Solution0055.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
1、题目:给定一个非负整数数组nums,你最初位于数组的第一个下标,数组中的每个元素代表你在该位置可以跳跃的最大长度,判断你是否能够到达最后一个下标。
77
2、题目简化:求索引 i 位置可以跳跃的最大长度,该长度是否大于等于最后一个索引位置
88
3、定义dp数组:dp[i]表示索引 i 位置能够跳跃到的最大长度
9-
4、状态转移方程:dp[i] = max(dp[i - 1], i + nums[i]);
10-
5、初始化:dp[0] = nums[0];
9+
4、初始化:
10+
1)dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化
11+
2)dp[0] = nums[0];
12+
5、状态转移方程:dp[i] = max(dp[i - 1], i + nums[i]);
1113
6、遍历dp数组填表:一个for循环遍历dp数组,根据状态转移方程推断计算未知结果并填表
1214
7、返回结果:在状态转移前后进行跳跃长度判断以快速得出结果,没希望跳过去、已经足够跳过去
1315
*/

leetcode_Java/Solution0062.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
1、题目:一个机器人位于一个 m x n 网格的左上角,机器人每次只能向下或者向右移动一步,机器人试图达到网格的右下角,问总共有多少条不同的路径?
77
2、题目简化:求从(0,0)到(m-1,n-1)的不同路径条数
88
3、定义dp数组:dp[i][j]表示到达位置(i,j)的不同路径条数
9-
4、状态转移方程:dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 即上方和左方的不同路径条数相加
10-
5、初始化:首行首列只有一条路径,初始化为1
9+
4、初始化:
10+
1)二维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化
11+
2)首行首列只有一条路径,初始化为1
12+
5、状态转移方程:dp[i][j] = dp[i - 1][j] + dp[i][j - 1] 即上方和左方的不同路径条数相加
1113
6、遍历dp数组填表:两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置不同路径条数并填表,直到终点,获得结果
1214
7、返回结果:最后一个状态就是结果
1315
*/

leetcode_Java/Solution0064.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
1、题目:给定一个包含非负整数的 m x n 网格 grid ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。说明:每次只能向下或者向右移动一步。
77
2、题目简化:求从 (0,0) 到达 (m-1,n-1) 位置的最小路径和
88
3、定义dp数组:本题可以直接在原数组操作。grid[i][j] 表示到达 (i,j) 位置的最小路径和
9-
4、状态转移方程:grid[i][j] += Math.min(grid[i - 1][j], grid[i][j - 1]); 即上方或左方的最小路径和
10-
5、初始化:首行首列的路径和进行累加初始化
9+
4、初始化:
10+
1)二维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化
11+
2)首行首列的路径和进行累加初始化
12+
5、状态转移方程:grid[i][j] += Math.min(grid[i - 1][j], grid[i][j - 1]); 即上方或左方的最小路径和
1113
6、遍历顺序:两个for循环遍历二维dp数组每个位置,根据状态转移方程计算该位置的最小路径和并填表,直到终点,获得结果
1214
*/
1315
class Solution {

leetcode_Java/Solution0121.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
1、定义dp数组:
77
dp[i][0] 表示第i天交易结束后不持有股票的最大利润
88
dp[i][1] 表示第i天交易结束后持有股票的最大利润
9-
2、状态转移方程
9+
2、初始化
10+
dp[0][0] = 0 表示第0天不持有股票,最大利润为0。创建数组时默认为0,可省略
11+
dp[0][1] = -prices[0] 表示第0天持有股票,最大利润为-prices[0]
12+
3、状态转移方程
1013
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
1114
第i天不持有股票 前一天不持有股票 前一天持有股票且今天卖出
1215
dp[i][1] = Math.max(dp[i - 1][1], -prices[i]); // 注意:只能买卖一次,所以买入时的利润为-prices[i]
1316
第i天持有股票 前一天持有股票 今天买入
14-
3、初始化
15-
dp[0][0] = 0 表示第0天不持有股票,最大利润为0。创建数组时默认为0,可省略
16-
dp[0][1] = -prices[0] 表示第0天持有股票,最大利润为-prices[0]
1717
4、遍历dp数组填表:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果
1818
5、返回结果:最后一个不持有股票的状态就是结果
1919

leetcode_Java/Solution0122.java

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,14 +6,14 @@
66
1、定义dp数组:
77
dp[i][0] 表示第i天交易结束后不持有股票的最大利润
88
dp[i][1] 表示第i天交易结束后持有股票的最大利润
9-
2、状态转移方程
9+
2、初始化
10+
dp[0][0] = 0 表示第0天不持有股票,最大利润为0。创建数组时默认为0,可省略
11+
dp[0][1] = -prices[0] 表示第0天持有股票,最大利润为-prices[0]
12+
3、状态转移方程
1013
dp[i][0] = Math.max(dp[i - 1][0], dp[i - 1][1] + prices[i]);
1114
第i天不持有股票 前一天不持有股票 前一天持有股票且今天卖出
1215
dp[i][1] = Math.max(dp[i - 1][1], dp[i - 1][0] - prices[i]); // 注意:可以买卖多次,所以买入时的利润包含之前所得利润,即dp[i - 1][0] - prices[i]
1316
第i天持有股票 前一天持有股票 前一天不持有股票且今天买入
14-
3、初始化
15-
dp[0][0] = 0 表示第0天不持有股票,最大利润为0。创建数组时默认为0,可省略
16-
dp[0][1] = -prices[0] 表示第0天持有股票,最大利润为-prices[0]
1717
4、遍历dp数组填表:一个for循环遍历数组,根据状态转移方程直接取dp数组的已知结果计算未知结果
1818
5、返回结果:最后一个不持有股票的状态就是结果
1919

leetcode_Java/Solution0139.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,10 @@
66
1、题目:给你一个字符串 s 和一个字符串列表 wordDict 作为字典。请你判断是否可以利用字典中出现的单词拼接出 s。注意:不要求字典中出现的单词全部都使用,并且字典中的单词可以重复使用。
77
2、题目简化:字符串s能否由单词列表拼出
88
3、定义dp数组:dp[i]表示前i个字符是否能由单词拼出
9-
4、状态转移方程:dp[i] = dp[j] && wordDict.contains(s.substring(j, i))
10-
5、初始化:dp[0] = true,表示字符串为空字符时的情况,方便递推判断
9+
4、初始化:
10+
1)一维dp数组扩容:增加空字符串这一最小规模的情况,方便初始化
11+
2)dp[0] = true,表示字符串为空字符时的情况,方便递推判断
12+
5、状态转移方程:dp[i] = dp[j] && wordDict.contains(s.substring(j, i))
1113
6、遍历dp数组填表:
1214
1)解释一:第一个for循环用于遍历dp数组未知位置,第二个for循环用于遍历dp数组已知位置,得到已知结果后根据状态转移方程推断计算未知结果并填表
1315
2)解释二:固定未知位置,由前面已知推断当前结果。固定第i个字符的位置,然后从头开始遍历到i位置,判断s[0,j)和s[j,i)是否能由单词拼出

leetcode_Java/Solution0152.java

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -29,10 +29,12 @@ public int maxProduct(int[] nums) {
2929
1、题目:给你一个整数数组 nums ,请你找出数组中乘积最大的非空连续子数组(该子数组中至少包含一个数字),并返回该子数组所对应的乘积。
3030
2、题目简化:求数组的最大乘积
3131
3、定义dp数组:dpMax[i]表示以i位置结尾的子数组最大乘积,dpMin[i]表示以i位置结尾的子数组最小乘积。由于存在负数,因此要保留当前的最大最小值。
32-
4、状态转移方程:
32+
4、初始化:
33+
1)一维dp数组不用扩容,直接根据dp数组的定义就可以直观地对应进行初始化
34+
2)dpMax[0] = dpMin[0] = nums[0];
35+
5、状态转移方程:
3336
dpMax[i] = Math.max(nums[i], Math.max(dpMax[i - 1] * nums[i], dpMin[i - 1] * nums[i]));
3437
dpMin[i] = Math.min(nums[i], Math.min(dpMax[i - 1] * nums[i], dpMin[i - 1] * nums[i]));
35-
5、初始化:dpMax[0] = dpMin[0] = nums[0];
3638
6、遍历dp数组填表:一个for循环遍历dp数组的未知位置,根据状态转移方程直接取dp数组的已知结果计算未知结果
3739
7、返回结果:dpMax[i]中取最大值
3840
*/

0 commit comments

Comments
 (0)