Open In App

Count all possible paths from source to destination in given 3D array

Given three integers M, N and K, the task is to count all the possible paths from the cell (0, 0, 0) to cell (M-1, N-1, K-1) in a matrix of size (M, N, K).  Movement is allowed only in three directions, which are along the positive direction of the three axes i.e. from any cell (i, j, k) movement is allowed to cells (i+1, j, k), (i, j+1, k) and (i, j, k+1).

Examples:



Input: M = 1, N = 1, K = 1
Output: 1
Explanation: As the source and destination both are same, there is only one possible way to stay there.

Input: M = 2, N = 2, K = 2
Output: 6
Explanation: The possible paths are :



  • (0, 0, 0) -> (0, 1, 0) -> (0, 1, 1) -> (1, 1, 1)
  • (0, 0, 0) -> (0, 1, 0) -> (1, 1, 0) -> (1, 1, 1)
  • (0, 0, 0) -> (1, 0, 0) -> (1, 1, 0) -> (1, 1, 1)
  • (0, 0, 0) -> (1, 0, 0) -> (1, 0, 1) -> (1, 1, 1)
  • (0, 0, 0) -> (0, 0, 1) -> (0, 1, 1) -> (1, 1, 1)
  • (0, 0, 0) -> (0, 0, 1) -> (1, 0, 1) -> (1, 1, 1)
 

Approach: This problem can be solved by using dynamic programming. Follow the below steps, to solve this problem:

dp[i][j][k] = dp[i – 1][j][k] + dp[i][j – 1][k] + dp[i][j][k – 1]

Below is the implementation of the above approach:




// C++ code for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find to the number of ways
// from the cell(0, 0, 0)
// to cell(M-1, N-1, K-1)
int numberOfWays(int M, int N, int K)
{
    vector<vector<vector<int> > > dp(
        M, vector<vector<int> >(
               N, vector<int>(K)));
 
    // Initialising dp
    dp[0][0][0] = 1;
 
    for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
            for (int k = 0; k < K; ++k) {
                if (i == 0 and j == 0
                    and k == 0) {
                    continue;
                }
                dp[i][j][k] = 0;
                if (i - 1 >= 0) {
                    dp[i][j][k] += dp[i - 1][j][k];
                }
                if (j - 1 >= 0) {
                    dp[i][j][k] += dp[i][j - 1][k];
                }
                if (k - 1 >= 0) {
                    dp[i][j][k] += dp[i][j][k - 1];
                }
            }
        }
    }
 
    return dp[M - 1][N - 1][K - 1];
}
 
// Driver Code
int main()
{
    int M = 2, N = 2, K = 2;
    cout << numberOfWays(M, N, K);
    return 0;
}




/*package whatever //do not write package name here */
import java.io.*;
 
class GFG {
 
  // Function to find to the number of ways
  // from the cell(0, 0, 0)
  // to cell(M-1, N-1, K-1)
  static int numberOfWays(int M, int N, int K)
  {
    int [][][] dp = new int[M][N][K];
 
 
    // Initialising dp
    dp[0][0][0] = 1;
 
    for (int i = 0; i < M; ++i) {
      for (int j = 0; j < N; ++j) {
        for (int k = 0; k < K; ++k) {
          if (i == 0 && j == 0
              && k == 0) {
            continue;
          }
          dp[i][j][k] = 0;
          if (i - 1 >= 0) {
            dp[i][j][k] += dp[i - 1][j][k];
          }
          if (j - 1 >= 0) {
            dp[i][j][k] += dp[i][j - 1][k];
          }
          if (k - 1 >= 0) {
            dp[i][j][k] += dp[i][j][k - 1];
          }
        }
      }
    }
 
    return dp[M - 1][N - 1][K - 1];
  }
 
  // Driver Code
  public static void main (String[] args)
  {
    int M = 2, N = 2, K = 2;
    System.out.println(numberOfWays(M, N, K));
  }
}
 
// This code is contributed by Potta Lokesh




# Python code for the above approach
 
# Function to find to the number of ways
# from the cell(0, 0, 0)
# to cell(M-1, N-1, K-1)
def numberOfWays(M, N, K):
    dp = [[[0 for i in range(K)] for j in range(N)] for k in range(M)]
     
    # Initialising dp
    dp[0][0][0] = 1;
 
    for i in range(M):
        for j in range(N):
            for k in range(K):
                if (i == 0 and j == 0 and k == 0):
                    continue;
                dp[i][j][k] = 0;
                if (i - 1 >= 0):
                    dp[i][j][k] += dp[i - 1][j][k];
                if (j - 1 >= 0):
                    dp[i][j][k] += dp[i][j - 1][k];
                if (k - 1 >= 0):
                    dp[i][j][k] += dp[i][j][k - 1];
    return dp[M - 1][N - 1][K - 1];
 
# Driver Code
 
M = 2
N = 2
K = 2;
print(numberOfWays(M, N, K));
 
# This code is contributed by gfgking




/*package whatever //do not write package name here */
using System;
 
class GFG {
 
  // Function to find to the number of ways
  // from the cell(0, 0, 0)
  // to cell(M-1, N-1, K-1)
  static int numberOfWays(int M, int N, int K)
  {
    int[, , ] dp = new int[M, N, K];
 
    // Initialising dp
    dp[0, 0, 0] = 1;
 
    for (int i = 0; i < M; ++i) {
      for (int j = 0; j < N; ++j) {
        for (int k = 0; k < K; ++k) {
          if (i == 0 && j == 0 && k == 0) {
            continue;
          }
          dp[i, j, k] = 0;
          if (i - 1 >= 0) {
            dp[i, j, k] += dp[i - 1, j, k];
          }
          if (j - 1 >= 0) {
            dp[i, j, k] += dp[i, j - 1, k];
          }
          if (k - 1 >= 0) {
            dp[i, j, k] += dp[i, j, k - 1];
          }
        }
      }
    }
 
    return dp[M - 1, N - 1, K - 1];
  }
 
  // Driver Code
  public static void Main(string[] args)
  {
    int M = 2, N = 2, K = 2;
    Console.WriteLine(numberOfWays(M, N, K));
  }
}
 
// This code is contributed by ukasp.




<script>
    // JavaScript code for the above approach
 
 
    // Function to find to the number of ways
    // from the cell(0, 0, 0)
    // to cell(M-1, N-1, K-1)
    const numberOfWays = (M, N, K) => {
        let dp = new Array(M).fill(0).map(() => new Array(N).fill(0).map(() => new Array(K).fill(0)));
        // Initialising dp
        dp[0][0][0] = 1;
 
        for (let i = 0; i < M; ++i) {
            for (let j = 0; j < N; ++j) {
                for (let k = 0; k < K; ++k) {
                    if (i == 0 && j == 0
                        && k == 0) {
                        continue;
                    }
                    dp[i][j][k] = 0;
                    if (i - 1 >= 0) {
                        dp[i][j][k] += dp[i - 1][j][k];
                    }
                    if (j - 1 >= 0) {
                        dp[i][j][k] += dp[i][j - 1][k];
                    }
                    if (k - 1 >= 0) {
                        dp[i][j][k] += dp[i][j][k - 1];
                    }
                }
            }
        }
 
        return dp[M - 1][N - 1][K - 1];
    }
 
    // Driver Code
 
    let M = 2, N = 2, K = 2;
    document.write(numberOfWays(M, N, K));
 
// This code is contributed by rakeshsahni
 
</script>

 
 

Output
6

 

Time Complexity: O(M*N*K)
Space Complexity: O(M*N*K)

Efficient approach : Optimize space complexity

In previous approach we can see that the dp[i][j][k] is depend upon dp[i – 1][j][k], dp[i][j – 1][k] and dp[i][j][k – 1] so we can convert 3d matric into current and previous 2d matrix where i-1 refer to previous and i refer to current.

Implantation steps : 

Implementation :




// C++ code for the above approach
 
#include <bits/stdc++.h>
using namespace std;
 
// Function to find to the number of ways
// from the cell(0, 0, 0)
// to cell(M-1, N-1, K-1)
int numberOfWays(int M, int N, int K)
{
    vector<vector<int> > curr(N, vector<int>(K, 0));
    vector<vector<int> > prev(N, vector<int>(K, 0));
 
    // Initialising dp
    prev[0][0] = 1;
    curr[0][0] = 1;
 
    for (int i = 0; i < M; ++i) {
        for (int j = 0; j < N; ++j) {
            for (int k = 0; k < K; ++k) {
                if (i == 0 and j == 0 and k == 0) {
                    continue;
                }
                curr[j][k] = 0;
                if (i - 1 >= 0) {
                    curr[j][k] += prev[j][k];
                }
                if (j - 1 >= 0) {
                    curr[j][k] += curr[j - 1][k];
                }
                if (k - 1 >= 0) {
                    curr[j][k] += curr[j][k - 1];
                }
            }
        }
        prev = curr;
    }
 
    return curr[N - 1][K - 1];
}
 
// Driver Code
int main()
{
    int M = 2, N = 2, K = 2;
    cout << numberOfWays(M, N, K);
    return 0;
}
 
// this code is contributed by bhardwajji




public class Main {
 
    // Function to find to the number of ways
    // from the cell(0, 0, 0)
    // to cell(M-1, N-1, K-1)
    public static int numberOfWays(int M, int N, int K)
    {
        int[][] curr = new int[N][K];
        int[][] prev = new int[N][K];
 
        prev[0][0] = 1;
        curr[0][0] = 1;
 
        for (int i = 0; i < M; ++i) {
            for (int j = 0; j < N; ++j) {
                for (int k = 0; k < K; ++k) {
                    if (i == 0 && j == 0 && k == 0) {
                        continue;
                    }
                    curr[j][k] = 0;
                    if (i - 1 >= 0) {
                        curr[j][k] += prev[j][k];
                    }
                    if (j - 1 >= 0) {
                        curr[j][k] += curr[j - 1][k];
                    }
                    if (k - 1 >= 0) {
                        curr[j][k] += curr[j][k - 1];
                    }
                }
            }
            for (int j = 0; j < N; j++) {
                prev[j] = curr[j].clone();
            }
        }
        return curr[N - 1][K - 1];
    }
 
    public static void main(String[] args)
    {
        int M = 2, N = 2, K = 2;
        System.out.println(numberOfWays(M, N, K));
    }
}




# Function to find the number of ways
# from the cell(0, 0, 0)
# to cell(M-1, N-1, K-1)
 
 
def numberOfWays(M, N, K):
    curr = [[0 for _ in range(K)] for _ in range(N)]
    prev = [[0 for _ in range(K)] for _ in range(N)]
 
    # Initializing dp
    prev[0][0] = 1
    curr[0][0] = 1
 
    for i in range(M):
        for j in range(N):
            for k in range(K):
                if i == 0 and j == 0 and k == 0:
                    continue
                curr[j][k] = 0
                if i - 1 >= 0:
                    curr[j][k] += prev[j][k]
                if j - 1 >= 0:
                    curr[j][k] += curr[j - 1][k]
                if k - 1 >= 0:
                    curr[j][k] += curr[j][k - 1]
            prev[j] = curr[j].copy()  # Create a new list for prev[j]
 
    return curr[N - 1][K - 1]
 
 
# Driver code
M, N, K = 2, 2, 2
print(numberOfWays(M, N, K))




// Javascript code for the above approach
 
// Function to find to the number of ways
// from the cell(0, 0, 0)
// to cell(M-1, N-1, K-1)
function numberOfWays(M, N, K) {
let curr = new Array(N);
let prev = new Array(N);
 
for (let i = 0; i < N; i++) {
curr[i] = new Array(K).fill(0);
prev[i] = new Array(K).fill(0);
}
 
// Initialising dp
prev[0][0] = 1;
curr[0][0] = 1;
 
for (let i = 0; i < M; i++) {
for (let j = 0; j < N; j++) {
for (let k = 0; k < K; k++) {
if (i === 0 && j === 0 && k === 0) {
continue;
}
curr[j][k] = 0;
if (i - 1 >= 0) {
curr[j][k] += prev[j][k];
}
if (j - 1 >= 0) {
curr[j][k] += curr[j - 1][k];
}
if (k - 1 >= 0) {
curr[j][k] += curr[j][k - 1];
}
}
}
for (let j = 0; j < N; j++) {
prev[j] = [...curr[j]];
}
}
return curr[N - 1][K - 1];
}
 
const M = 2;
const N = 2;
const K = 2;
 
console.log(numberOfWays(M, N, K));




// C# code for the above approach
 
using System;
 
public class MainClass {
 
    // Function to find to the number of ways
    // from the cell(0, 0, 0)
    // to cell(M-1, N-1, K-1)
    public static int NumberOfWays(int M, int N, int K)
    {
        int[, ] curr = new int[N, K];
        int[, ] prev = new int[N, K];
 
        // Initialising dp
        prev[0, 0] = 1;
        curr[0, 0] = 1;
 
        for (int i = 0; i < M; ++i) {
            for (int j = 0; j < N; ++j) {
                for (int k = 0; k < K; ++k) {
                    if (i == 0 && j == 0 && k == 0) {
                        continue;
                    }
                    curr[j, k] = 0;
                    if (i - 1 >= 0) {
                        curr[j, k] += prev[j, k];
                    }
                    if (j - 1 >= 0) {
                        curr[j, k] += curr[j - 1, k];
                    }
                    if (k - 1 >= 0) {
                        curr[j, k] += curr[j, k - 1];
                    }
                }
            }
            prev = curr.Clone() as int[, ];
        }
 
        return curr[N - 1, K - 1];
    }
 
    public static void Main(string[] args)
    {
        int M = 2, N = 2, K = 2;
        Console.WriteLine(NumberOfWays(M, N, K));
    }
}

Output : 

6

Time Complexity: O(M*N*K)
Auxiliary Space: O(N*K)
 


Article Tags :