Skip to content

Commit b09b091

Browse files
committed
62 63 递归 + dp
1 parent 9c1d2af commit b09b091

4 files changed

Lines changed: 161 additions & 0 deletions

File tree

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
"""
2+
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
3+
4+
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
5+
6+
问总共有多少条不同的路径?
7+
8+
例如,上图是一个7 x 3 的网格。有多少可能的路径?
9+
10+
说明:m 和 n 的值均不超过 100。
11+
12+
示例 1:
13+
14+
输入: m = 3, n = 2
15+
输出: 3
16+
解释:
17+
从左上角开始,总共有 3 条路径可以到达右下角。
18+
1. 向右 -> 向右 -> 向下
19+
2. 向右 -> 向下 -> 向右
20+
3. 向下 -> 向右 -> 向右
21+
示例 2:
22+
23+
输入: m = 7, n = 3
24+
输出: 28
25+
===========================
26+
老套路先试试回溯+缓存
27+
优化 碰触到右或者下的边可直接返回1
28+
缓存为m*n数组,mn启点 00终点,这样变量能少传两个。
29+
"""
30+
31+
32+
class Solution:
33+
def uniquePaths(self, m: int, n: int) -> int:
34+
if not m or not n:
35+
return 0
36+
return self.rec(m-1, n-1, [[None for _ in range(n)] for _ in range(m)])
37+
38+
def rec(self, m, n, cache):
39+
if not m or not n:
40+
return 1
41+
42+
if cache[m][n] is None:
43+
cache[m][n] = self.rec(m-1, n, cache) + self.rec(m, n-1, cache)
44+
45+
return cache[m][n]
46+
47+
48+
s = Solution()
49+
print(s.uniquePaths(3, 2) == 3)
50+
print(s.uniquePaths(7, 3) == 28)
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
"""
2+
老套路 DP递推 自底向上
3+
00默认是终点递推比较容易
4+
"""
5+
6+
7+
class Solution:
8+
def uniquePaths(self, m: int, n: int) -> int:
9+
if not m or not n:
10+
return 0
11+
12+
cache = [1] * n
13+
for _m in range(1, m):
14+
_cache = [1] * n
15+
for _n in range(1, n):
16+
_cache[_n] = _cache[_n-1] + cache[_n]
17+
18+
cache = _cache
19+
20+
return cache[n - 1]
21+
22+
23+
s = Solution()
24+
print(s.uniquePaths(3, 2) == 3)
25+
print(s.uniquePaths(7, 3) == 28)
26+
print(s.uniquePaths(3, 7) == 28)
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
"""
2+
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
3+
4+
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
5+
6+
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
7+
8+
===================================
9+
老套路 先递归
10+
直接用初始化数组当缓存
11+
用None取代本来是结果0的点位 避免重复计算 -1取代障碍物点位
12+
"""
13+
14+
15+
class Solution:
16+
def uniquePathsWithObstacles(self, obstacleGrid) -> int:
17+
if not obstacleGrid or not obstacleGrid[0]:
18+
return 0
19+
20+
for m in range(len(obstacleGrid)):
21+
for n in range(len(obstacleGrid[0])):
22+
obstacleGrid[m][n] = None if obstacleGrid[m][n] == 0 else -1
23+
24+
return self.rec(0, 0, len(obstacleGrid)-1, len(obstacleGrid[0])-1, obstacleGrid)
25+
26+
def rec(self, m, n, m_max, n_max, grid):
27+
if m > m_max or n > n_max:
28+
return 0
29+
30+
if grid[m][n] == -1:
31+
return 0
32+
33+
if m == m_max and n == n_max:
34+
return 1
35+
36+
if grid[m][n] is None:
37+
grid[m][n] = self.rec(m+1, n, m_max, n_max, grid) + self.rec(m, n+1, m_max, n_max, grid)
38+
39+
return grid[m][n]
40+
41+
42+
s = Solution()
43+
print(s.uniquePathsWithObstacles([
44+
[0, 0, 0],
45+
[0, 1, 0],
46+
[0, 0, 0]
47+
]))
48+
print(s.uniquePathsWithObstacles([[1, 0]]))
49+
print(s.uniquePathsWithObstacles([[0, 1]]))
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
"""
2+
尝试DP
3+
"""
4+
5+
6+
class Solution:
7+
def uniquePathsWithObstacles(self, grid) -> int:
8+
if not grid or not grid[0]:
9+
return 0
10+
11+
for m in range(len(grid)):
12+
for n in range(len(grid[0])):
13+
if grid[m][n] == 1:
14+
grid[m][n] = 0
15+
continue
16+
17+
if m == 0 and n == 0:
18+
grid[m][n] = 1
19+
continue
20+
21+
if n > 0:
22+
grid[m][n] += grid[m][n-1]
23+
if m > 0:
24+
grid[m][n] += grid[m-1][n]
25+
26+
return grid[m][n]
27+
28+
29+
s = Solution()
30+
print(s.uniquePathsWithObstacles([
31+
[0, 0, 0],
32+
[0, 1, 0],
33+
[0, 0, 0]
34+
]))
35+
print(s.uniquePathsWithObstacles([[1, 0]]))
36+
print(s.uniquePathsWithObstacles([[0, 1]]))

0 commit comments

Comments
 (0)