Count of possible paths from top left to bottom right of a M x N matrix by moving right, down or diagonally
Last Updated :
22 Aug, 2023
Given 2 integers M and N, the task is to find the count of all the possible paths from top left to the bottom right of an M x N matrix with the constraints that from each cell you can either move only to right or down or diagonally
Examples:
Input: M = 3, N = 3
Output: 13
Explanation: There are 13 paths as follows: VVHH, VHVH, HVVH, DVH, VDH, VHHV, HVHV, DHV, HHVV, HDV, VHD, HVD, and DD where V represents vertical, H represents horizontal, and D represents diagonal paths.
Input: M = 2, N = 2
Output: 3
Approach: The idea is to use recursion to find the total number of paths. This approach is very similar to the one discussed in this article. Follow the steps below to solve the problem:
- If M or N equals 1, then return 1.
- Else create a recursive function numberOfPaths() call the same function for values {M-1, N}, {M, N-1} and {M-1, N-1} representing vertical, horizontal and diagonal movement respectively.
Below is the implementation of the above approach:
C++
#include <iostream>
using namespace std;
int numberOfPaths( int M, int N)
{
if (M == 1 || N == 1)
return 1;
return numberOfPaths(M - 1, N)
+ numberOfPaths(M, N - 1)
+ numberOfPaths(M - 1, N - 1);
}
int main()
{
cout << numberOfPaths(3, 3);
return 0;
}
|
Java
import java.util.*;
public class GFG
{
static int numberOfPaths( int M, int N)
{
if (M == 1 || N == 1 )
return 1 ;
return numberOfPaths(M - 1 , N)
+ numberOfPaths(M, N - 1 )
+ numberOfPaths(M - 1 , N - 1 );
}
public static void main(String args[])
{
System.out.print(numberOfPaths( 3 , 3 ));
}
}
|
Python
def numberOfPaths(M, N):
if (M = = 1 or N = = 1 ):
return 1
return numberOfPaths(M - 1 , N) \
+ numberOfPaths(M, N - 1 ) \
+ numberOfPaths(M - 1 , N - 1 )
print (numberOfPaths( 3 , 3 ))
|
C#
using System;
public class GFG
{
static int numberOfPaths( int M, int N)
{
if (M == 1 || N == 1)
return 1;
return numberOfPaths(M - 1, N)
+ numberOfPaths(M, N - 1)
+ numberOfPaths(M - 1, N - 1);
}
public static void Main(String []args)
{
Console.Write(numberOfPaths(3, 3));
}
}
|
Javascript
<script>
function numberOfPaths(M, N) {
if (M == 1 || N == 1)
return 1;
return numberOfPaths(M - 1, N)
+ numberOfPaths(M, N - 1)
+ numberOfPaths(M - 1, N - 1);
}
document.write(numberOfPaths(3, 3));
</script>
|
Time Complexity: O(3M*N)
Auxiliary Space: O(N), where N is recursion stack space.
Efficient Approach: Dp (using Memoization)
C++
#include <bits/stdc++.h>
using namespace std;
static int dp[1001][1001];
int numberOfPaths( int M, int N)
{
if (M == 1 || N == 1)
return 1;
if (dp[M][N] != -1) {
return dp[M][N];
}
return dp[M][N] = numberOfPaths(M - 1, N)
+ numberOfPaths(M, N - 1)
+ numberOfPaths(M - 1, N - 1);
}
int main()
{
memset (dp,-1, sizeof (dp));
cout << numberOfPaths(3, 3);
return 0;
}
|
Java
import java.util.*;
public class GFG {
static int [][] dp = new int [ 1001 ][ 1001 ];
static int numberOfPaths( int M, int N)
{
if (M == 1 || N == 1 )
return 1 ;
if (dp[M][N] != - 1 ) {
return dp[M][N];
}
dp[M][N] = numberOfPaths(M - 1 , N)
+ numberOfPaths(M, N - 1 )
+ numberOfPaths(M - 1 , N - 1 );
return dp[M][N];
}
public static void main(String args[])
{
for ( int i = 0 ; i < 1001 ; i++)
for ( int j = 0 ; j < 1001 ; j++)
dp[i][j] = - 1 ;
System.out.println(numberOfPaths( 3 , 3 ));
}
}
|
Python
dp = [[ - 1 for i in range ( 1001 )] for j in range ( 1001 )]
def numberOfPaths(M, N):
if (M = = 1 or N = = 1 ):
return 1
if (dp[M][N] ! = - 1 ):
return dp[M][N]
dp[M][N] = numberOfPaths(M - 1 , N) + numberOfPaths(M,
N - 1 ) + numberOfPaths(M - 1 , N - 1 )
return dp[M][N]
print (numberOfPaths( 3 , 3 ))
|
C#
using System;
class GFG {
static int [, ] dp = new int [1001, 1001];
static int numberOfPaths( int M, int N)
{
if (M == 1 || N == 1)
return 1;
if (dp[M, N] != -1) {
return dp[M, N];
}
dp[M, N] = numberOfPaths(M - 1, N)
+ numberOfPaths(M, N - 1)
+ numberOfPaths(M - 1, N - 1);
return dp[M, N];
}
public static void Main()
{
for ( int i = 0; i < 1001; i++)
for ( int j = 0; j < 1001; j++)
dp[i, j] = -1;
Console.Write(numberOfPaths(3, 3));
}
}
|
Javascript
<script>
var dp = new Array(1001);
for ( var i = 0; i < dp.length; i++) {
dp[i] = new Array(1001);
}
function numberOfPaths(M, N)
{
if (M == 1 || N == 1)
return 1;
if (dp[M][N] != -1) {
return dp[M][N];
}
dp[M][N] = numberOfPaths(M - 1, N)
+ numberOfPaths(M, N - 1)
+ numberOfPaths(M - 1, N - 1);
return dp[M][N];
}
for (let i = 0; i < 1001; i++){
for (let j = 0; j < 1001; j++){
dp[i][j] = -1;
}}
document.write(numberOfPaths(3, 3));
</script>
|
Time Complexity: O(M*N), The time complexity of this approach is O(M*N). Since there are MN subproblems, and each subproblem takes constant time to solve. This is because the solution to each subproblem is a sum of three previously computed subproblems. Therefore, the total time taken is proportional to the number of subproblems, which is M*N.
Auxiliary Space: O(M*N), The space complexity of this approach is also O(M*N). This is because we are using a two-dimensional array of size (M+1) * (N+1) to store the results of the subproblems. Each cell of this array requires constant space, and hence the total space required is proportional to the number of subproblems, which is M*N.
Efficient Approach: Dp (using Tables)
Follow below steps to solve the problem using bottom up approach:
- Initialize dp[1][1] = 1 and dp[1][1..N-1] = 1, dp[1..M-1][1] = 1
- For each i = 1 to M, do the following:
a. For each j = 1 to N, do the following:
i. Compute dp[i][j] as dp[i-1][j] + dp[i][j-1] + dp[i-1][j-1]
- Return dp[M][N]
Below is the implementation of the approach:
C++
#include <bits/stdc++.h>
using namespace std;
int numberOfPaths( int M, int N) {
int dp[M + 1][N + 1];
for ( int i = 1; i <= M; i++) {
for ( int j = 1; j <= N; j++) {
if (i == 1 || j == 1) {
dp[i][j] = 1;
}
}
}
for ( int i = 2; i <= M; i++) {
for ( int j = 2; j <= N; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1]
+ dp[i - 1][j - 1];
}
}
return dp[M][N];
}
int main() {
cout << numberOfPaths(3, 3);
return 0;
}
|
Java
import java.util.Arrays;
public class GFG {
static int numberOfPaths( int m, int n) {
int [][] dp = new int [m + 1 ][n + 1 ];
for ( int i = 0 ; i <= m; i++) {
Arrays.fill(dp[i], 1 );
}
for ( int i = 2 ; i <= m; i++) {
for ( int j = 2 ; j <= n; j++) {
dp[i][j] = dp[i - 1 ][j] + dp[i][j - 1 ]
+ dp[i - 1 ][j - 1 ];
}
}
return dp[m][n];
}
public static void main(String[] args) {
System.out.println(numberOfPaths( 3 , 3 ));
}
}
|
Python
def numberOfPaths(m, n):
dp = [[ 0 for x in range (n + 1 )] for x in range (m + 1 )]
for i in range (m + 1 ):
for j in range (n + 1 ):
if i = = 1 or j = = 1 :
dp[i][j] = 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 ] + dp[i - 1 ][j - 1 ]
return dp[m][n]
m = 3
n = 3
print (numberOfPaths(m, n))
|
C#
using System;
class GFG {
static int numberOfPaths( int m, int n)
{
int [, ] dp = new int [m + 1, n + 1];
for ( int i = 0; i <= m; i++) {
for ( int j = 0; j <= n; j++) {
dp[i, j] = 1;
}
}
for ( int i = 2; i <= m; i++) {
for ( int j = 2; j <= n; j++) {
dp[i, j] = dp[i - 1, j] + dp[i, j - 1]
+ dp[i - 1, j - 1];
}
}
return dp[m, n];
}
static void Main( string [] args)
{
Console.WriteLine(numberOfPaths(3, 3));
Console.ReadKey();
}
}
|
Javascript
function numberOfPaths(M, N) {
let dp = new Array(M + 1).fill(0).map(() => new Array(N + 1).fill(0));
for (let i = 1; i <= M; i++) {
for (let j = 1; j <= N; j++) {
if (i === 1 || j === 1) {
dp[i][j] = 1;
}
}
}
for (let i = 2; i <= M; i++) {
for (let j = 2; j <= N; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1] + dp[i - 1][j - 1];
}
}
return dp[M][N];
}
console.log(numberOfPaths(3, 3));
|
Time Complexity: O(M*N) as two nested loops are executing one from 1 to M and other from 1 to N where M and N are rows and columns respectively.
Space Complexity: O(M*N) as 2D array dp has been created of size M+1 and N+1 where M and N are rows and columns respectively.
Share your thoughts in the comments
Please Login to comment...