@@ -56,8 +56,8 @@ console.log(minimumTotal(tringle)); //11
5656
5757动态规划和 DFS 区别
5858
59- - 二叉树 子问题是没有交集 ,所以大部分二叉树都用递归或者分治法,即 DFS ,就可以解决
60- - 像 triangle 这种是有重复走的情况,** 子问题是有交集** ,所以可以用动态规划来解决
59+ - 二叉树子问题是没有交集 ,所以大部分二叉树都用递归或者分治法,即DFS ,就可以解决。
60+ - 像 triangle 这种是有重复走的情况,** 子问题是有交集** ,所以可以用动态规划来解决。
6161
6262** 动态规划三个特性** :
6363
@@ -73,7 +73,11 @@ console.log(minimumTotal(tringle)); //11
7373
7474 如果用一句话概括一下,那就是,不同的决策序列,到达某个相同的阶段时,可能会产生重复的状态。所以才会用一个数组记录中间结果,避免重复计算。
7575
76- 动态规划,自底向上 这里变成一位数组,因为层号实际上可以不用记录,每次记录上一层的值,到当前层就把以前的覆盖到,动态规划运用场景其中一条就是最优子结构,往下走不用回头一定是最优的
76+ 动态规划,自底向上
77+
78+ 这里变成一位数组,因为层号实际上可以不用记录,每次记录上一层的值,到当前层就把以前的覆盖到,动态规划运用场景其中一条就是最优子结构,往下走不用回头一定是最优的。
79+
80+ ` f(i,j)=min(f(i+1,j),f(i+1,j+1))+triangle[i][j] `
7781
7882``` js
7983var minimumTotal = function (tringle ){
@@ -100,7 +104,7 @@ Function(x) {
100104}
101105```
102106
103- 动态规划:是一种解决问 题的思想 ,大规模问题的结果,是由小规模问 题的结果运算得来的。动态规划可用递归来实现(Memorization Search)
107+ 动态规划:是一种解决问题的思想 ,大规模问题的结果,是由小规模问 题的结果运算得来的。动态规划可用递归来实现(Memorization Search)
104108
105109## 使用场景
106110
@@ -136,4 +140,90 @@ Function(x) {
136140
137141> 注意点
138142>
139- > - 贪心算法大多题目靠背答案,所以如果能用动态规划就尽量用动规,不用贪心算法
143+ > - 贪心算法大多题目靠背答案,所以如果能用动态规划就尽量用动规,不用贪心算法
144+
145+ ## 1、矩阵类型(10%)
146+
147+ ##### [ 64. 最小路径和] ( https://leetcode-cn.com/problems/minimum-path-sum/ )
148+
149+ 给定一个包含非负整数的 ` *m* x *n* ` 网格 ` grid ` ,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。** 说明:** 每次只能向下或者向右移动一步。
150+
151+ ``` js
152+ var minPathSum = function (grid ) {
153+ let m = grid .length
154+ let n = grid[0 ].length
155+ for (let i = 1 ; i < m; i++ ) {
156+ grid[i][0 ] += grid[i - 1 ][0 ]
157+ }
158+ for (let i = 1 ; i < n; i++ ) {
159+ grid[0 ][i] += grid[0 ][i - 1 ]
160+ }
161+ for (let i = 1 ; i < m; i++ ) {
162+ for (let j = 1 ; j < n; j++ ) {
163+ grid[i][j] = Math .min (grid[i - 1 ][j], grid[i][j - 1 ]) + grid[i][j]
164+ }
165+ }
166+ return grid[m - 1 ][n - 1 ]
167+ };
168+ ```
169+
170+ ##### [ 62. 不同路径] ( https://leetcode-cn.com/problems/unique-paths/ )
171+
172+ 一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为 “Start” )。机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为 “Finish” )。问总共有多少条不同的路径?
173+
174+ ``` js
175+ var uniquePaths = function (m , n ) {
176+ let dp = new Array (m).fill (new Array (n).fill (1 )) // 第一行和第一列都是1
177+ for (let i = 1 ; i < m; i++ ) {
178+ for (let j = 1 ; j < n; j++ ) {
179+ dp[i][j] = dp[i - 1 ][j] + dp[i][j - 1 ]
180+ }
181+ }
182+ return dp[m - 1 ][n - 1 ]
183+ };
184+ ```
185+
186+ ##### [ 63. 不同路径 II] ( https://leetcode-cn.com/problems/unique-paths-ii/ )
187+
188+ 同上,不过增加了障碍物。
189+
190+ > 思路:第一行(列)遇到障碍物之前置为1,之后置为0(包括障碍物)
191+
192+ ``` js
193+ var uniquePathsWithObstacles = function (obstacleGrid ) {
194+ let m = obstacleGrid .length
195+ let n = obstacleGrid[0 ].length
196+ if (obstacleGrid[0 ][0 ] === 1 ) {
197+ return 0
198+ }
199+ for (let i = 0 ; i < m; i++ ) {
200+ if (obstacleGrid[i][0 ] === 1 ) {
201+ for (let j = i; j < m; j++ ) {
202+ obstacleGrid[j][0 ] = 0
203+ }
204+ break
205+ }
206+ obstacleGrid[i][0 ] = 1
207+ }
208+ for (let i = 1 ; i < n; i++ ) {
209+ if (obstacleGrid[0 ][i] === 1 ) {
210+ for (let j = i; j < n; j++ ) {
211+ obstacleGrid[0 ][j] = 0
212+ }
213+ break
214+ }
215+ obstacleGrid[0 ][i] = 1
216+ }
217+ for (let i = 1 ; i < m; i++ ) {
218+ for (let j = 1 ; j < n; j++ ) {
219+ if (obstacleGrid[i][j] === 1 ) {
220+ obstacleGrid[i][j] = 0
221+ } else {
222+ obstacleGrid[i][j] = obstacleGrid[i - 1 ][j] + obstacleGrid[i][j - 1 ]
223+ }
224+ }
225+ }
226+ return obstacleGrid[m - 1 ][n - 1 ]
227+ };
228+ ```
229+
0 commit comments