leetcode 63. 不同路径 II 64. 寻找两个正序数组的中位数

leetcode 63. 不同路径 II 64. 寻找两个正序数组的中位数

63. 不同路径 II

难度中等710

一个机器人位于一个 m x n 网格的左上角 (起始点在下图中标记为“Start” )。

机器人每次只能向下或者向右移动一步。机器人试图达到网格的右下角(在下图中标记为“Finish”)。

现在考虑网格中有障碍物。那么从左上角到右下角将会有多少条不同的路径?

img

网格中的障碍物和空位置分别用 10 来表示。

示例 1:

img

输入:obstacleGrid = [[0,0,0],[0,1,0],[0,0,0]]
输出:2
解释:
3x3 网格的正中间有一个障碍物。
从左上角到右下角一共有 2 条不同的路径:
1. 向右 -> 向右 -> 向下 -> 向下
2. 向下 -> 向下 -> 向右 -> 向右

示例 2:

img

输入:obstacleGrid = [[0,1],[0,0]]
输出:1

提示:

  • m == obstacleGrid.length

  • n == obstacleGrid[i].length

  • 1 <= m, n <= 100

  • obstacleGrid[i][j]01

    # -*- 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:

img

输入: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))
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

matianlongg

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值