leetcode 63. 不同路径 II 64. 寻找两个正序数组的中位数
63. 不同路径 II
难度中等710
一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。
机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。
现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?
网格中的障碍物和空位置分别用 1
和 0
来表示。
示例 1:
输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右
示例 2:
输入:obstacleGrid = [[0,1],[0,0]]
输出:1
提示:
-
m == obstacleGrid.length
-
n == obstacleGrid[i].length
-
1 <= m, n <= 100
-
obstacleGrid[i][j]
为0
或1
# -*- coding: utf-8 -*- # !/usr/bin/env python # @Time : 2021/12/14 14:27 # @Author : mtl # @Desc : *** # @File : 63.py # @Software: PyCharm from typing import List class Solution: def uniquePathsWithObstacles(self, obstacleGrid: List[List[int]]) -> int: if obstacleGrid[-1][-1] == 1: return 0 directions = [[0,1], [1,0]] ans = 0 m,n = len(obstacleGrid), len(obstacleGrid[0]) def dfs(pos_x, pos_y): nonlocal ans if pos_y == m - 1 and pos_x == n - 1: ans += 1 if pos_y >= m or pos_x >= n or obstacleGrid[pos_y][pos_x] == 1: return for i in range(2): direction_x, direction_y = directions[i] dfs(pos_x + direction_x, pos_y + direction_y) dfs(0, 0) return ans def uniquePathsWithObstacles2(self, obstacleGrid: List[List[int]]) -> int: if obstacleGrid[-1][-1] == 1 or obstacleGrid[0][0] == 1: return 0 u = obstacleGrid u[0][0] = 1 m, n = len(obstacleGrid), len(obstacleGrid[0]) for i in range(1, n): u[0][i] = 1 if u[0][i] == 0 and u[0][i - 1] == 1 else 0 for i in range(1, m): u[i][0] = 1 if u[i][0] == 0 and u[i - 1][0] == 1 else 0 for i in range(1, n): for j in range(1, m): u[j][i] = 0 if u[j][i] == 1 else u[j-1][i] + u[j][i-1] return obstacleGrid[-1][-1] if __name__ == '__main__': obstacleGrid = [[0,1],[0,0]] obstacleGrid = [[0,0],[0,1]] obstacleGrid = [[0 for _ in range(7)] for _ in range(3)] # obstacleGrid[2][3] = 1 obstacleGrid[2][4] = 1 # obstacleGrid[0][3] = 1 obstacleGrid = [[0, 1], [0, 0]] obstacleGrid = [[0,1,0],[0,0,0],[0,0,0]] print(Solution().uniquePathsWithObstacles2(obstacleGrid))
64. 最小路径和
难度中等1121
给定一个包含非负整数的 *m* x *n*
网格 grid
,请找出一条从左上角到右下角的路径,使得路径上的数字总和为最小。
**说明:**每次只能向下或者向右移动一步。
示例 1:
输入:grid = [[1,3,1],[1,5,1],[4,2,1]]
输出:7
解释:因为路径 1→3→1→1→1 的总和最小。
示例 2:
输入:grid = [[1,2,3],[4,5,6]]
输出:12
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 200
0 <= grid[i][j] <= 100
# -*- coding: utf-8 -*-
# !/usr/bin/env python
# @Time : 2021/12/29 17:48
# @Author : mtl
# @Desc : ***
# @File : 64.py
# @Software: PyCharm
from typing import List
class Solution:
def minPathSum(self, grid: List[List[int]]) -> int:
diretion = [[0, 1], [1, 0]]
m, n = len(grid), len(grid[0])
ans = [[-1 for _ in range(n)] for _ in range(m)]
ans[0][0] = grid[0][0]
for i in range(m):
for j in range(n):
for d in diretion:
if i+d[0] < m and j + d[1] < n:
ni, nj = d[0] + i, d[1] + j
ans[ni][nj] = ans[i][j] + grid[ni][nj] if ans[ni][nj] == -1 else min(ans[i][j] + grid[ni][nj], ans[ni][nj])
return ans[-1][-1]
def minPathSum(self, grid: List[List[int]]) -> int:
m, n = len(grid), len(grid[0])
for i in range(m):
for j in range(n):
if i == 0:
if j==0:continue
grid[i][j] = grid[i][j] + grid[i][j - 1]
elif j==0:
grid[i][j] = grid[i][j] + grid[i-1][j]
else:
grid[i][j] = min(grid[i - 1][j], grid[i][j - 1]) + grid[i][j]
return grid[-1][-1]
# def minPathSum(self, grid):
# dp = [float('inf')] * (len(grid[0]) + 1)
# dp[1] = 0
# for row in grid:
# for idx, num in enumerate(row):
# dp[idx + 1] = min(dp[idx], dp[idx + 1]) + num
# return dp[-1]
if __name__ == '__main__':
grid = [[1, 3, 1],
[1, 5, 1],
[4, 2, 1]]
# grid = [[1, 2, 3], [4, 5, 6]]
print(Solution().minPathSum(grid))
# return dp[-1]
if __name__ == '__main__':
grid = [[1, 3, 1],
[1, 5, 1],
[4, 2, 1]]
# grid = [[1, 2, 3], [4, 5, 6]]
print(Solution().minPathSum(grid))