【LeetCode】62. Unique Paths 解题报告(Python)
题目地址:https://leetcode.com/problems/unique-paths/
题目描述
A robot is located at the top-left corner of a m x n grid (marked ‘Start’ in the diagram below).
The robot can only move either down or right at any point in time. The robot is trying to reach the bottom-right corner of the grid (marked ‘Finish’ in the diagram below).
How many possible unique paths are there?
Above is a 7 x 3 grid. How many possible unique paths are there?
Note: m and n will be at most 100.
Example 1:
Input: m = 3, n = 2
Output: 3
Explanation:
From the top-left corner, there are a total of 3 ways to reach the bottom-right corner:
1. Right -> Right -> Down
2. Right -> Down -> Right
3. Down -> Right -> Right
Example 2:
Input: m = 7, n = 3
Output: 28
解法1:组合数
共走 m + n − 2 m+n-2 m+n−2次,其中向右 m − 1 m-1 m−1次,即为组合数 C ( m + n − 2 , m − 1 ) C(m+n-2,m-1) C(m+n−2,m−1)
直接求解
class Solution:
def comb(self, m: int, n: int) -> int:
ans = 1
for i in range(n):
ans *= m-i
for i in range(n):
ans /= i+1
return int(ans)
def uniquePaths(self, m: int, n: int) -> int:
return self.comb(m+n-2, min(m-1, n-1))
防溢出(python大数不会溢出,给一个思路)
从后往前计算,先计算 ( m − n + 1 ) / 1 = x 1 (m-n+1)/1=x_{1} (m−n+1)/1=x1,再计算 ( m − n + 2 ) ∗ x 1 / 2 = x 2 (m-n+2)*x_{1}/2=x_{2} (m−n+2)∗x1/2=x2,再计算 ( N − M + 3 ) ∗ x 2 / 3 (N-M+3)*x_{2}/3 (N−M+3)∗x2/3,这样能防止溢出(这样计算能够保证每次的计算结果都是整数,因为每次的计算结果就是一个组合数)
class Solution:
def comb(self, m: int, n: int) -> int:
ans = 1
for i in range(1, n+1):
ans = int(ans*(m-n+i)/i)
return ans
def uniquePaths(self, m: int, n: int) -> int:
return self.comb(m+n-2, min(m-1, n-1))
C ( m , n ) = C ( m − 1 , n ) + C ( m − 1 , n − 1 ) C(m,n) = C(m-1,n)+C(m-1,n-1) C(m,n)=C(m−1,n)+C(m−1,n−1)
类似动态规划,不可直接递归,有重复子问题
class Solution:
def comb(self, m: int, n: int) -> int:
dp = [[0 for i in range(n+1)] for j in range(m+1)]
for i in range(m+1):
dp[i][0] = 1
for i in range(n+1):
dp[i][i] = 1
for i in range(1, m+1):
for j in range(1, min(i, n+1)):
dp[i][j] = dp[i-1][j] + dp[i-1][j-1]
return dp[m][n]
def uniquePaths(self, m: int, n: int) -> int:
return self.comb(m+n-2, m-1)
解法2:动态规划
到达某一点的路径数等于到达它上一点的路径数与它左边的路径数之和。也即,起点到点
(
i
,
j
)
(i, j)
(i,j)的路径总数:
w
a
y
s
[
i
]
[
j
]
ways[i][j]
ways[i][j]等于起点到点
(
i
,
j
−
1
)
(i, j-1)
(i,j−1)的总数:$ways[i][j-1]
加
上
起
点
到
点
加上 起点到点
加上起点到点(i-1, j)
总
数
:
w
a
y
s
[
i
−
1
]
[
j
]
总数:ways[i-1][j]
总数:ways[i−1][j]。于是我们就得到递推关系式:
w
a
y
s
[
i
]
[
j
]
=
w
a
y
s
[
i
]
[
j
−
1
]
+
w
a
y
s
[
i
−
1
]
[
j
]
ways[i][j] = ways[i][j-1] + ways[i-1][j]
ways[i][j]=ways[i][j−1]+ways[i−1][j]
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [[0 for i in range(n + 1)] for j in range(m + 1)]
for i in range(m+1):
dp[i][1] = 1
for i in range(n+1):
dp[1][i] = 1
for i in range(2, m+1):
for j in range(2, n+1):
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[m][n]
一维数组,一行一行刷新,节省内存:
class Solution:
def uniquePaths(self, m: int, n: int) -> int:
dp = [1 for i in range(n)]
for i in range(m-1):
for j in range(1, n):
dp[j] += dp[j-1]
return dp[n-1]