# Minimum cost to reach from the top-left to the bottom-right corner of a matrix

Given an N * M matrix mat[][] consisting of lower case characters, the task is to find the minimum cost to reach from the cell mat[0][0] to the cell mat[N-1][M-1]. If you are at a cell mat[i][j], you can jump to the cells mat[i+1][j], mat[i][j+1], mat[i-1][j], mat[i][j-1] (without going out of bounds) with a cost of 1. Additionally, you can jump to any cell mat[m][n] such that mat[n][m] = mat[i][j] with a cost of 0.

Examples:

Input: mat[][] = {“abc”, “efg”, “hij”}
Output: 4
One of the shortest path will be:
{0, 0} -> {0, 1} -> {0, 2} -> {1, 2} -> {2, 2}
All the edges have a weight of 1, thus the answer is 4.

Input: mat[][] = {“abc”, “efg”, “hbj”}
Output: 2
{0, 0} -> {0, 1} -> {2, 1} -> {2, 2}
1 + 0 + 1 = 2

## Recommended: Please try your approach on {IDE} first, before moving on to the solution.

Naive approach: One approach for solving this problem will be 0-1 BFS. Visualise the setup as a graph with N * M nodes. All the nodes will be connected to adjacent nodes with an edge of weight 1 and the nodes with the same characters with an edge with weight 0. Now, BFS can be used to find the shortest path from the cell mat[0][0] to the cell mat[N-1][M-1]. The time complexity of this will be O((N * M)2) because the number of edges will be of the order O((N * M)2).

Efficient approach: For each character X, find all the characters it is adjacent to. Now, create a graph with a number of nodes as the number of distinct characters in the string each representing a character.
Each node X will have an edge of weight 1 with all the nodes representing the characters adjacent to the character X in the real graph. Then a BFS can be run from the node representing mat[0][0] to the node representing mat[N-1][M-1] in this new graph. The time complexity of this approach will be O(N * M) for pre-processing the graph and the time complexity for running the BFS can be considered constant.

Below is the implementation of the above approach:

## C++

 // C++ implementation of the approach #include using namespace std;    const int MAX = 26;    // Function to return // the value (x - 97) int f(int x) {     return x - 'a'; }    // Fucntion to return the minimum cost int findMinCost(vector arr) {     int n = arr.size();     int m = arr[0].size();        // Graph     vector > gr(MAX);        // Adjacency matrix     bool edge[MAX][MAX];        // Initialising the adjacency matrix     for (int k = 0; k < MAX; k++)         for (int l = 0; l < MAX; l++)             edge[k][l] = 0;        // Creating the adjacency matrix     for (int i = 0; i < n; i++)         for (int j = 0; j < m; j++) {             if (i + 1 < n and !edge[f(arr[i][j])][f(arr[i + 1][j])]) {                 gr[f(arr[i][j])].push_back(f(arr[i + 1][j]));                 edge[f(arr[i][j])][f(arr[i + 1][j])] = 1;             }             if (j - 1 >= 0 and !edge[f(arr[i][j])][f(arr[i][j - 1])]) {                 gr[f(arr[i][j])].push_back(f(arr[i][j - 1]));                 edge[f(arr[i][j])][f(arr[i][j - 1])] = 1;             }             if (j + 1 < m and !edge[f(arr[i][j])][f(arr[i][j + 1])]) {                 gr[f(arr[i][j])].push_back(f(arr[i][j + 1]));                 edge[f(arr[i][j])][f(arr[i][j + 1])] = 1;             }             if (i - 1 >= 0 and !edge[f(arr[i][j])][f(arr[i - 1][j])]) {                 gr[f(arr[i][j])].push_back(f(arr[i - 1][j]));                 edge[f(arr[i][j])][f(arr[i - 1][j])] = 1;             }         }        // Queue to perform BFS     queue q;     q.push(arr[0][0] - 'a');        // Visited array     bool v[MAX] = { 0 };        // To store the depth of BFS     int d = 0;        // BFS     while (q.size()) {            // Number of elements in         // the current level         int cnt = q.size();            // Inner loop         while (cnt--) {                // Current element             int curr = q.front();                // Popping queue             q.pop();                // If the current node has             // already been visited             if (v[curr])                 continue;             v[curr] = 1;                // Checking if the current             // node is the required node             if (curr == arr[n - 1][m - 1] - 'a')                 return d;                // Iterating through the current node             for (auto it : gr[curr])                 q.push(it);         }            // Updating the depth         d++;     }        return -1; }    // Driver code int main() {     vector arr = { "abc",                            "def",                            "gbi" };        cout << findMinCost(arr);        return 0; }

## Python3

 # Python3 implementation of the approach MAX = 26    # Function to return # the value (x - 97) def f(x):     return ord(x) - ord('a')    # Fucntion to return the minimum cost def findMinCost( arr):     global MAX     n = len(arr)     m = len(arr[0])        # Graph     gr = []            for x in range(MAX):         gr.append([])        # Adjacency matrix     edge = []        # Initialising the adjacency matrix     for k in range(MAX):         edge.append([])         for l in range(MAX):             edge[k].append(0)        # Creating the adjacency matrix     for i in range(n):         for j in range(m):              if (i + 1 < n and edge[f(arr[i][j])][f(arr[i + 1][j])] == 0):                  gr[f(arr[i][j])].append(f(arr[i + 1][j]))                 edge[f(arr[i][j])][f(arr[i + 1][j])] = 1                            if (j - 1 >= 0 and edge[f(arr[i][j])][f(arr[i][j - 1])] == 0):                  gr[f(arr[i][j])].append(f(arr[i][j - 1]))                 edge[f(arr[i][j])][f(arr[i][j - 1])] = 1                            if (j + 1 < m and edge[f(arr[i][j])][f(arr[i][j + 1])] == 0):                  gr[f(arr[i][j])].append(f(arr[i][j + 1]))                 edge[f(arr[i][j])][f(arr[i][j + 1])] = 1                            if (i - 1 >= 0 and edge[f(arr[i][j])][f(arr[i - 1][j])] == 0):                  gr[f(arr[i][j])].append(f(arr[i - 1][j]))                 edge[f(arr[i][j])][f(arr[i - 1][j])] = 1                    # Queue to perform BFS     q = []     q.append(ord(arr[0][0]) - ord('a'))        # Visited array     v = []     for i in range(MAX):         v.append(0)        # To store the depth of BFS     d = 0        # BFS     while (len(q) > 0):             # Number of elements in         # the current level         cnt = len(q)            # Inner loop         while (cnt > 0):              cnt = cnt - 1                            # Current element             curr = q[0]                # Popping queue             q.pop(0)                # If the current node has             # already been visited             if (v[curr] != 0):                 continue             v[curr] = 1                            # Checking if the current             # node is the required node             if (curr == (ord(arr[n - 1][m - 1]) - ord('a'))):                 return d                # Iterating through the current node             for it in gr[curr]:                 q.append(it)                    # Updating the depth         d = d + 1        return -1    # Driver code arr =[ "abc","def","gbi" ] print( findMinCost(arr))    # This code is contributed by Arnab Kundu

## C#

 // C# implementation of the approach using System; using System.Collections.Generic;    class GFG  {        static int MAX = 26;        // Function to return     // the value (x - 97)     static int f(int x)     {         return x - 'a';     }        // Function to return the minimum cost     static int findMinCost(String[] arr)      {         int n = arr.Length;         int m = arr[0].Length;            // Graph         List[] gr = new List[MAX];         for (int i = 0; i < MAX; i++)             gr[i] = new List();            // Adjacency matrix         bool[,] edge = new bool[MAX, MAX];            // Initialising the adjacency matrix         for (int k = 0; k < MAX; k++)             for (int l = 0; l < MAX; l++)                 edge[k,l] = false;            // Creating the adjacency matrix         for (int i = 0; i < n; i++)             for (int j = 0; j < m; j++)              {                 if (i + 1 < n && !edge[f(arr[i][j]),f(arr[i + 1][j])])                  {                     gr[f(arr[i][j])].Add(f(arr[i + 1][j]));                     edge[f(arr[i][j]), f(arr[i + 1][j])] = true;                 }                 if (j - 1 >= 0 && !edge[f(arr[i][j]),f(arr[i][j - 1])])                 {                     gr[f(arr[i][j])].Add(f(arr[i][j - 1]));                     edge[f(arr[i][j]), f(arr[i][j - 1])] = true;                 }                 if (j + 1 < m && !edge[f(arr[i][j]),f(arr[i][j + 1])])                  {                     gr[f(arr[i][j])].Add(f(arr[i][j + 1]));                     edge[f(arr[i][j]), f(arr[i][j + 1])] = true;                 }                 if (i - 1 >= 0 && !edge[f(arr[i][j]),f(arr[i - 1][j])])                  {                     gr[f(arr[i][j])].Add(f(arr[i - 1][j]));                     edge[f(arr[i][j]), f(arr[i - 1][j])] = true;                 }             }            // Queue to perform BFS         Queue q = new Queue();         q.Enqueue(arr[0][0] - 'a');            // Visited array         bool[] v = new bool[MAX];            // To store the depth of BFS         int d = 0;            // BFS         while (q.Count > 0)         {                // Number of elements in             // the current level             int cnt = q.Count;                // Inner loop             while (cnt-- > 0)             {                    // Current element                 int curr = q.Peek();                    // Popping queue                 q.Dequeue();                    // If the current node has                 // already been visited                 if (v[curr])                     continue;                 v[curr] = true;                    // Checking if the current                 // node is the required node                 if (curr == arr[n - 1][m - 1] - 'a')                     return d;                    // Iterating through the current node                 foreach (int it in gr[curr])                     q.Enqueue(it);             }                // Updating the depth             d++;         }            return -1;     }        // Driver code     public static void Main(String[] args)      {         String[] arr = { "abc", "def", "gbi" };            Console.Write(findMinCost(arr));     } }    // This code is contributed by 29AjayKumar

Output:

2

GeeksforGeeks has prepared a complete interview preparation course with premium videos, theory, practice problems, TA support and many more features. Please refer Placement 100 for details

My Personal Notes arrow_drop_up

Check out this Author's contributed articles.

If you like GeeksforGeeks and would like to contribute, you can also write an article using contribute.geeksforgeeks.org or mail your article to contribute@geeksforgeeks.org. See your article appearing on the GeeksforGeeks main page and help other Geeks.

Please Improve this article if you find anything incorrect by clicking on the "Improve Article" button below.

Improved By : 29AjayKumar, andrew1234