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

Last Updated : 10 Feb, 2023

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:
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:
{0, 0} -> {0, 1} -> {2, 1} -> {2, 2}
1 + 0 + 1 = 2

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'``;` `}`   `// Function 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<``int``> 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;` `}`

## Java

 `// Java implementation of the approach` `import` `java.util.*;`   `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` `        ``Vector[] gr = ``new` `Vector[MAX];` `        ``for` `(``int` `i = ``0``; i < MAX; i++)` `            ``gr[i] = ``new` `Vector();`   `        ``// Adjacency matrix` `        ``boolean``[][] edge = ``new` `boolean``[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].charAt(j))][f(arr[i + ``1``].charAt(j))]) ` `                ``{` `                    ``gr[f(arr[i].charAt(j))].add(f(arr[i + ``1``].charAt(j)));` `                    ``edge[f(arr[i].charAt(j))][f(arr[i + ``1``].charAt(j))] = ``true``;` `                ``}` `                ``if` `(j - ``1` `>= ``0` `&& !edge[f(arr[i].charAt(j))][f(arr[i].charAt(j - ``1``))])` `                ``{` `                    ``gr[f(arr[i].charAt(j))].add(f(arr[i].charAt(j - ``1``)));` `                    ``edge[f(arr[i].charAt(j))][f(arr[i].charAt(j - ``1``))] = ``true``;` `                ``}` `                ``if` `(j + ``1` `< m && !edge[f(arr[i].charAt(j))][f(arr[i].charAt(j + ``1``))]) ` `                ``{` `                    ``gr[f(arr[i].charAt(j))].add(f(arr[i].charAt(j + ``1``)));` `                    ``edge[f(arr[i].charAt(j))][f(arr[i].charAt(j + ``1``))] = ``true``;` `                ``}` `                ``if` `(i - ``1` `>= ``0` `&& !edge[f(arr[i].charAt(j))][f(arr[i - ``1``].charAt(j))]) ` `                ``{` `                    ``gr[f(arr[i].charAt(j))].add(f(arr[i - ``1``].charAt(j)));` `                    ``edge[f(arr[i].charAt(j))][f(arr[i - ``1``].charAt(j))] = ``true``;` `                ``}` `            ``}`   `        ``// Queue to perform BFS` `        ``Queue q = ``new` `LinkedList();` `        ``q.add(arr[``0``].charAt(``0``) - ``'a'``);`   `        ``// Visited array` `        ``boolean``[] v = ``new` `boolean``[MAX];`   `        ``// To store the depth of BFS` `        ``int` `d = ``0``;`   `        ``// BFS` `        ``while` `(q.size() > ``0``)` `        ``{`   `            ``// Number of elements in` `            ``// the current level` `            ``int` `cnt = q.size();`   `            ``// Inner loop` `            ``while` `(cnt-- > ``0``)` `            ``{`   `                ``// Current element` `                ``int` `curr = q.peek();`   `                ``// Popping queue` `                ``q.remove();`   `                ``// 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``].charAt(m - ``1``) - ``'a'``)` `                    ``return` `d;`   `                ``// Iterating through the current node` `                ``for` `(Integer it : gr[curr])` `                    ``q.add(it);` `            ``}`   `            ``// Updating the depth` `            ``d++;` `        ``}`   `        ``return` `-``1``;` `    ``}`   `    ``// Driver code` `    ``public` `static` `void` `main(String[] args) ` `    ``{` `        ``String[] arr = { ``"abc"``, ``"def"``, ``"gbi"` `};`   `        ``System.out.print(findMinCost(arr));`   `    ``}` `}`   `// This code is contributed by 29AjayKumar`

## Python3

 `# Python3 implementation of the approach` `MAX` `=` `26`   `# Function to return` `# the value (x - 97)` `def` `f(x):` `    ``return` `ord``(x) ``-` `ord``(``'a'``)`   `# Function 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<``int``>[] gr = ``new` `List<``int``>[MAX];` `        ``for` `(``int` `i = 0; i < MAX; i++)` `            ``gr[i] = ``new` `List<``int``>();`   `        ``// 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<``int``> q = ``new` `Queue<``int``>();` `        ``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`

## Javascript

 `// Javascript implementation of the approach`   `const MAX = 26;`   `// Function to return the value (x - 97)` `function` `f(x) {` `  ``return` `x.charCodeAt(0) - ``'a'``.charCodeAt(0);` `}`   `// Function to return the minimum cost` `function` `findMinCost(arr) {` `  ``let n = arr.length;` `  ``let m = arr[0].length;`   `  ``// Graph` `  ``let gr = [];`   `  ``for` `(let x = 0; x < MAX; x++) {` `    ``gr.push([]);` `  ``}`   `  ``// Adjacency matrix` `  ``let edge = [];`   `  ``// Initializing the adjacency matrix` `  ``for` `(let k = 0; k < MAX; k++) {` `    ``edge.push([]);` `    ``for` `(let l = 0; l < MAX; l++) {` `      ``edge[k].push(0);` `    ``}` `  ``}`   `  ``// Creating the adjacency matrix` `  ``for` `(let i = 0; i < n; i++) {` `    ``for` `(let j = 0; j < m; j++) {` `      ``if` `(i + 1 < n && edge[f(arr[i][j])][f(arr[i + 1][j])] === 0) {` `        ``gr[f(arr[i][j])].push(f(arr[i + 1][j]));` `        ``edge[f(arr[i][j])][f(arr[i + 1][j])] = 1;` `      ``}`   `      ``if` `(j - 1 >= 0 && edge[f(arr[i][j])][f(arr[i][j - 1])] === 0) {` `        ``gr[f(arr[i][j])].push(f(arr[i][j - 1]));` `        ``edge[f(arr[i][j])][f(arr[i][j - 1])] = 1;` `      ``}`   `      ``if` `(j + 1 < m && edge[f(arr[i][j])][f(arr[i][j + 1])] === 0) {` `        ``gr[f(arr[i][j])].push(f(arr[i][j + 1]));` `        ``edge[f(arr[i][j])][f(arr[i][j + 1])] = 1;` `      ``}`   `      ``if` `(i - 1 >= 0 && edge[f(arr[i][j])][f(arr[i - 1][j])] === 0) {` `        ``gr[f(arr[i][j])].push(f(arr[i - 1][j]));` `        ``edge[f(arr[i][j])][f(arr[i - 1][j])] = 1;` `      ``}` `    ``}` `  ``}`   `  ``// Queue to perform BFS` `  ``let q = [];` `  ``q.push(arr[0][0].charCodeAt(0) - ``'a'``.charCodeAt(0));`   `  ``// Visited array` `  ``let v = [];` `  ``for` `(let i = 0; i < MAX; i++) {` `    ``v.push(0);` `  ``}`   `  ``// To store the depth of BFS` `  ``let d = 0;`   `// BFS` `while` `(q.length > 0) {` `// Number of elements in the current level` `let cnt = q.length;`   `// Inner loop` `while` `(cnt > 0) {` `cnt--;`     `// Current element` `let curr = q[0];`   `// Popping queue` `q.shift();`   `// 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 === (arr[n - 1][m - 1].charCodeAt(0) - ``'a'``.charCodeAt(0))) ``return` `d;`   `// Iterating through the current node` `for` `(let it of gr[curr]) {` `  ``q.push(it);` `}` `}`   `// Updating the depth` `d++;` `}`   `return` `-1;` `};`   `// Driver code` `let arr = [``'abc'``, ``'def'``, ``'gbi'``];` `console.log(findMinCost(arr));`

Output:

`2`

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