62. Unique Paths
Approach 1: Combinatorics
Let us assume that the m = 3
and n = 3
The path will then always be 4 moves long: DDRR, DRDR, RDRD..... where R means Right, and D means Down.
On observation you can see that the path length will always be m-1
R's and n-1
D's to reach the bottom corner and the total path length is m+n-2
We can convert this problem into a linear one:
Given a string of length
m + n - 2
fill it withm-1
R's andn-1
D's
Using combinatorics we can say that it is: m+n-2
choose m-1
i.e. (m+n-2)C(m-1)
which is evaluated as the answer below
class Solution(object):
def uniquePaths(self, m, n):
"""
:type m: int
:type n: int
:rtype: int
"""
di = {0:1, 1:1, 2:2}
def factorial(n):
if n in di:
return di[n]
else:
di[n] = n*factorial(n-1)
return di[n]
return int(factorial(m+n-2)/(factorial(m-1)*factorial(n-1)))
Time Complexity: O(m+n-2)
Space Complexity: O(m+n-2)
Approach 2: Use multiplication instead of factorial
Same math as above but just a different way of evaluation
Instead of using a memo-ised factorial function we can simply calculate it as below since we know the values of m
and n
. This solution is more memory efficient than above
class Solution:
def uniquePaths(self, m, n):
"""
https://leetcode.com/problems/unique-paths/description/
:type m: int
:type n: int
:rtype: int
"""
ma, mi = max(m-1,n-1) , min(m-1,n-1)
su = m + n - 2
k = 1
for i in range(su,ma,-1):
k = k * i
for i in range(1,mi+1):
k = k / i
return int(k)
Time Complexity: O(m+n-2)
Space Complexity: O(1)
Approach 3: Dynamic Programming
Since we can only move in 2 directions, dp[i][j] = dp[i-1][j] + dp[i][j-1]
where dp[i][j]
stands for the total number of paths till location(i,j)
As for the initial conditions: dp[i][0] = 1
for all i < m
and dp[0][j]
for all j < n
Using this we can get the total number of paths as follows:
class Solution:
def uniquePaths(self, m, n):
"""
https://leetcode.com/problems/unique-paths/description/
:type m: int
:type n: int
:rtype: int
"""
dp = [[1]*n for _ in range(m)]
for i in range(m):
dp[i][0] = 1
for j in range(n):
dp[0][j] = 1
for i in range(1,m):
for j in range(1,n):
dp[i][j] = dp[i-1][j] + dp[i][j-1]
return dp[m-1][n-1]
Last updated