📌  相关文章
📜  从原点开始不访问(X,Y)即可到达矩阵(M,N)的方式数(1)

📅  最后修改于: 2023-12-03 15:36:16.745000             🧑  作者: Mango

从原点开始不访问(X,Y)即可到达矩阵(M,N)的方式数

考虑给定一个矩阵 m ,矩阵大小为 MxN ,现在有一个机器人从矩阵的左上角 (0,0) 的位置开始移动。机器人每次可以向右或向下移动一步,直到到达矩阵的右下角 (M-1,N-1) 的位置。请问,从左上角出发,到达 (M-1,N-1) 的位置有多少种不同的走法?

除了上述情况,现在我们给出一个坐标 (X,Y) , 机器人不能通过该坐标前往。

例如,对于一个 3x3 的矩阵,其中 (1,1) 的位置不能走。那么从原点到 (2,2) 的走法数量为 2 , 从原点到 (2,0) 的走法数量为 3

解法

这是一道经典的动态规划问题。我们定义状态 dp(i,j) 为到达矩阵的 (i,j) 点的方案数。则有递推方程式:

(i,j) 是挡板时,dp(i,j) = 0

否则,有 dp(i, j) = dp(i-1, j) + dp(i, j-1)

初始状态为 dp(0,0) = 1

最终答案即为 dp(M-1, N-1)

代码实现
def uniquePaths(m: int, n: int, obstacle: List[List[int]]) -> int:
    dp = [[0] * n for _ in range(m)]
    dp[0][0] = 1
    for i in range(m):
        for j in range(n):
            if i == 0 and j == 0:
                continue
            if obstacle[i][j] == 1:
                continue
            if i == 0:
                dp[i][j] = dp[i][j-1]
            elif j == 0:
                dp[i][j] = dp[i-1][j]
            else:
                dp[i][j] = dp[i-1][j] + dp[i][j-1]
    return dp[m-1][n-1]

这里的 obstacle 是一个大小为 MxN 的二维数组,表示每个位置是否有障碍物。其中值为 1 表示当前位置为障碍,值为 0 表示当前位置没有障碍。

时间复杂度

该算法时间复杂度为 O(MN),空间复杂度为 O(MN)

另一种思路

除了上述解法,还有一种更为简单的解法,即组合数学,就是从左上角到右下角,需要向右移动 N-1 次,并向下移动 M-1 次。因此,总共需要走 M+N-2 步。这其中需要挑选 N-1 步向右走,或者挑选 M-1 步向下走。因此,答案即为组合数 $\binom{M+N-2}{N-1}$。

注意到,以上解法中,我们没有考虑到障碍物的信息。如果要考虑障碍物,只需要在计算组合数时,不考虑经过障碍物的路径即可。

代码实现
def uniquePaths(m: int, n: int, obstacle: List[List[int]]) -> int:
    total = m + n - 2
    right = n - 1
    res = 1
    for i in range(total, total-right, -1):
        res *= i
    for i in range(1, right+1):
        res //= i
    return res