# Minimum possible modifications in the matrix to reach destination

• Difficulty Level : Hard
• Last Updated : 13 Dec, 2021

Given a matrix of size N x M consisting of integers 1, 2, 3 and 4
Each value represents the possible movement from that cell:

```1 -> move left
2 -> move right
3 -> move up
4 -> move down.```

The task is to find the minimum possible changes required in the matrix such that there exists a path from (0, 0) to (N-1, M-1).

Examples:

Input : mat[][] = {{2, 2, 4},
{1, 1, 1},
{3, 3, 2}};
Output :
Change the value of mat[1][2] to 4. So the sequence of moves will be
(0, 0) -> (0, 1) -> (0, 2) -> (1, 2) -> (2, 2)

Input : mat[][] = {{2, 2, 1},
{4, 2, 3},
{4, 3, 2}}
Output :

Prerequisites:
1. Dijkstra’s Algorithm
2.0-1 BFS

Method 1

• Let’s consider each cell of the 2D matrix as a node of the weighted graph and each node can has at most four connected nodes(possible four directions). Each edge is weighted as:
• weight(U, V) = 0, if the direction of movement of node U points to V, else
• weight(U, V) = 1
• Now, this basically reduces to shortest path problem which can be computed using Dijkstra’s Algorithm

Below is the implementation of the above approach:

## C++

 `// CPP program to find minimum possible` `// changes required in the matrix` `#include ` `using` `namespace` `std;`   `// Function to find next possible node` `int` `nextNode(``int` `x, ``int` `y, ``int` `dir, ``int` `N, ``int` `M)` `{` `    ``if` `(dir == 1)` `        ``y--;` `    ``else` `if` `(dir == 2)` `        ``y++;` `    ``else` `if` `(dir == 3)` `        ``x--;` `    ``else` `        ``x++;`   `    ``// If node is out of matrix` `    ``if` `(!(x >= 0 && x < N && y >= 0 && y < M))` `        ``return` `-1;` `    ``else` `        ``return` `(x * N + y);` `}`   `// Prints shortest paths from src` `// to all other vertices` `int` `dijkstra(vector >* adj,` `             ``int` `src, ``int` `dest, ``int` `N, ``int` `M)` `{` `    ``// Create a set to store vertices` `    ``// that are bein preprocessed` `    ``set > setds;`   `    ``// Create a vector for distances` `    ``// and initialize all distances` `    ``// as infinite (large value)` `    ``vector<``int``> dist(N * M, INT_MAX);`   `    ``// Insert source itself in Set` `    ``// and initialize its distance as 0` `    ``setds.insert(make_pair(0, src));` `    ``dist[src] = 0;`   `    ``/* Looping till all shortest ` `        ``distance are finalized ` `        ``then setds will become empty */` `    ``while` `(!setds.empty()) {` `        ``// The first vertex in Set` `        ``// is the minimum distance` `        ``// vertex, extract it from set.` `        ``pair<``int``, ``int``> tmp = *(setds.begin());` `        ``setds.erase(setds.begin());`   `        ``// vertex label is stored in second` `        ``// of pair (it has to be done this` `        ``// way to keep the vertices sorted` `        ``// distance (distance must be` `        ``// first item in pair)` `        ``int` `u = tmp.second;`   `        ``// 'i' is used to get all adjacent` `        ``// vertices of a vertex` `        ``vector >::iterator i;` `        ``for` `(i = adj[u].begin();` `             ``i != adj[u].end(); ++i) {` `            ``// Get vertex label and weight` `            ``// of current adjacent of u.` `            ``int` `v = (*i).first;` `            ``int` `weight = (*i).second;`   `            ``// If there is shorter path from u to v` `            ``if` `(dist[v] > dist[u] + weight) {` `                ``// If distance of v is not` `                ``// INF then it must be` `                ``// in our set, so removing it` `                ``// and inserting again with` `                ``// updated less distance.` `                ``// Note : We extract only` `                ``// those vertices from Set` `                ``// for which distance is` `                ``// finalized. So for them,` `                ``// we would never reach here` `                ``if` `(dist[v] != INT_MAX)` `                    ``setds.erase(setds.find(` `                        ``{ dist[v], v }));`   `                ``// Updating distance of v` `                ``dist[v] = dist[u] + weight;` `                ``setds.insert(make_pair(dist[v], v));` `            ``}` `        ``}` `    ``}`   `    ``// Return the distance` `    ``return` `dist[dest];` `}`   `// Function to find minimum possible` `// changes required in the matrix` `int` `MinModifications(vector >& mat)` `{` `    ``int` `N = mat.size(), M = mat[0].size();`   `    ``// Converting given matrix to a graph` `    ``vector > adj[N * M];`   `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``for` `(``int` `j = 0; j < M; j++) {` `            ``// Each cell is a node,` `            ``// with label i*N + j` `            ``for` `(``int` `dir = 1; dir <= 4; dir++) {` `                ``// Label of node if we` `                ``// move in direction dir` `                ``int` `nextNodeLabel` `                    ``= nextNode(i, j, dir, N, M);`   `                ``// If invalid(out of matrix)` `                ``if` `(nextNodeLabel == -1)` `                    ``continue``;`   `                ``// If direction is same as mat[i][j]` `                ``if` `(dir == mat[i][j])` `                    ``adj[i * N + j].push_back(` `                        ``{ nextNodeLabel, 0 });` `                ``else` `                    ``adj[i * N + j].push_back(` `                        ``{ nextNodeLabel, 1 });` `            ``}` `        ``}` `    ``}`   `    ``// Applying dijkstra's algorithm` `    ``return` `dijkstra(adj, 0,` `                    ``(N - 1) * N + M - 1, N, M);` `}`   `// Driver code` `int` `main()` `{` `    ``vector > mat = { { 2, 2, 1 },` `                                 ``{ 4, 2, 3 },` `                                 ``{ 4, 3, 2 } };`   `    ``// Function call` `    ``cout << MinModifications(mat);`   `    ``return` `0;` `}`

## Python3

 `# Python 3 program to find minimum possible` `# changes required in the matrix` `import` `heapq as hq`   `# Function to find next possible node` `def` `nextNode(x, y, dirn, N, M):` `    ``if` `(dirn ``=``=` `1``):` `        ``y``-``=``1` `    ``elif` `(dirn ``=``=` `2``):` `        ``y``+``=``1` `    ``elif` `(dirn ``=``=` `3``):` `        ``x``-``=``1` `    ``else``:` `        ``x``+``=``1`   `    ``# If node is out of matrix` `    ``if` `(``not``(x >``=` `0` `and` `x < N ``and` `y >``=` `0` `and` `y < M)):` `        ``return` `-``1` `    ``else``:` `        ``return` `(x ``*` `N ``+` `y)`     `# Prints shortest paths from src` `# to all other vertices` `def` `dijkstra( adj, src, dest, N, M):` `    ``# Create a set to store vertices` `    ``# that are being preprocessed` `    ``setds``=``[]`   `    ``# Create a vector for distances` `    ``# and initialize all distances` `    ``# as infinite (large value)` `    ``dist``=``[``float``(``'inf'``)]``*``(N ``*` `M)`   `    ``# Insert source itself in Set` `    ``# and initialize its distance as 0` `    ``hq.heappush(setds,(``0``, src))` `    ``dist[src] ``=` `0`   `    ``# Looping till all shortest ` `    ``# distance are finalized ` `    ``# then setds will become empty ` `    ``while` `(setds) :` `        ``# The first vertex in Set` `        ``# is the minimum distance` `        ``# vertex, extract it from set.` `        ``tmp ``=` `hq.heappop(setds)`   `        ``# vertex label is stored in second` `        ``# of pair (it has to be done this` `        ``# way to keep the vertices sorted` `        ``# distance (distance must be` `        ``# first item in pair)` `        ``u ``=` `tmp[``1``]`   `        ``# 'i' is used to get all adjacent` `        ``# vertices of a vertex` `        ``for` `i ``in` `adj[u] :` `            ``# Get vertex label and weight` `            ``# of current adjacent of u.`   `            ``v ``=` `i[``0``]` `            ``weight ``=` `i[``1``]`   `            ``# If there is shorter path from u to v` `            ``if` `(dist[v] > dist[u] ``+` `weight):` `                ``# Updating distance of v` `                ``dist[v] ``=` `dist[u] ``+` `weight` `                ``hq.heappush(setds, (dist[v], v))` `            `  `        `  `    `    `    ``# Return the distance` `    ``return` `dist[dest]`     `# Function to find minimum possible` `# changes required in the matrix` `def` `MinModifications(mat):` `    ``N ``=` `len``(mat); M ``=` `len``(mat[``0``])`   `    ``# Converting given matrix to a graph` `    ``adj``=``[[] ``for` `_ ``in` `range``(N``*``M)]`   `    ``for` `i ``in` `range``(N):` `        ``for` `j ``in` `range``(M) :` `            ``# Each cell is a node,` `            ``# with label i*N + j` `            ``for` `dirn ``in` `range``(``1``, ``5``):` `                ``# Label of node if we` `                ``# move in direction dirn` `                ``nextNodeLabel``=` `nextNode(i, j, dirn, N, M)`   `                ``# If invalid(out of matrix)` `                ``if` `(nextNodeLabel ``=``=` `-``1``):` `                    ``continue`   `                ``# If direction is same as mat[i][j]` `                ``if` `(dirn ``=``=` `mat[i][j]):` `                    ``adj[i ``*` `N ``+` `j].append((nextNodeLabel, ``0``))` `                ``else``:` `                    ``adj[i ``*` `N ``+` `j].append((nextNodeLabel, ``1` `))` `            `  `        `  `    `    `    ``# Applying dijkstra's algorithm` `    ``return` `dijkstra(adj, ``0``,` `                    ``(N ``-` `1``) ``*` `N ``+` `M ``-` `1``, N, M)`     `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    ``mat ``=` `[[``2``, ``2``, ``1` `,],` `        ``[``4``, ``2``, ``3` `,],` `        ``[``4``, ``3``, ``2``]]  `   `    ``# Function call` `    ``print``(MinModifications(mat))`

Output:

`2`

Time Complexity :

Method 2
Here, edge weights are 0, and 1 only i.e it’s a 0-1 graph. The shortest path in such graphs can be found using 0-1 BFS.

Below is the implementation of the above approach:

## C++

 `// C++ program to find minimum` `// possible changes required` `// in the matrix` `#include ` `using` `namespace` `std;`   `// Function to find next possible node` `int` `nextNode(``int` `x, ``int` `y, ``int` `dir,` `             ``int` `N, ``int` `M)` `{` `    ``if` `(dir == 1)` `        ``y--;` `    ``else` `if` `(dir == 2)` `        ``y++;` `    ``else` `if` `(dir == 3)` `        ``x--;` `    ``else` `        ``x++;`   `    ``// If node is out of matrix` `    ``if` `(!(x >= 0 && x < N && y >= 0 && y < M))` `        ``return` `-1;` `    ``else` `        ``return` `(x * N + y);` `}`   `// Prints shortest distance` `// from given source to` `// every other vertex` `int` `zeroOneBFS(vector >* adj,` `               ``int` `src, ``int` `dest, ``int` `N, ``int` `M)` `{` `    ``// Initialize distances` `    ``// from given source` `    ``int` `dist[N * M];` `    ``for` `(``int` `i = 0; i < N * M; i++)` `        ``dist[i] = INT_MAX;`   `    ``// Double ended queue to do BFS.` `    ``deque<``int``> Q;` `    ``dist[src] = 0;` `    ``Q.push_back(src);`   `    ``while` `(!Q.empty()) {` `        ``int` `v = Q.front();` `        ``Q.pop_front();`   `        ``for` `(``auto` `i : adj[v]) {` `            ``// Checking for the optimal distance` `            ``if` `(dist[i.first] > dist[v]` `                                    ``+ i.second) {` `                ``dist[i.first] = dist[v]` `                                ``+ i.second;`   `                ``// Put 0 weight edges to front` `                ``// and 1 weight edges to back` `                ``// so that vertices are processed` `                ``// in increasing order of weights.` `                ``if` `(i.second == 0)` `                    ``Q.push_front(i.first);` `                ``else` `                    ``Q.push_back(i.first);` `            ``}` `        ``}` `    ``}`   `    ``// Shortest distance to` `    ``// reach destination` `    ``return` `dist[dest];` `}`   `// Function to find minimum possible` `// changes required in the matrix` `int` `MinModifications(vector >& mat)` `{` `    ``int` `N = mat.size(), M = mat[0].size();`   `    ``// Converting given matrix to a graph` `    ``vector > adj[N * M];`   `    ``for` `(``int` `i = 0; i < N; i++) {` `        ``for` `(``int` `j = 0; j < M; j++) {` `            ``// Each cell is a node` `            ``// with label i*N + j` `            ``for` `(``int` `dir = 1; dir <= 4; dir++) {` `                ``// Label of node if we` `                ``// move in direction dir` `                ``int` `nextNodeLabel = nextNode(i, j,` `                                             ``dir, N, M);`   `                ``// If invalid(out of matrix)` `                ``if` `(nextNodeLabel == -1)` `                    ``continue``;`   `                ``// If direction is same as mat[i][j]` `                ``if` `(dir == mat[i][j])` `                    ``adj[i * N + j].push_back(` `                        ``{ nextNodeLabel, 0 });` `                ``else` `                    ``adj[i * N + j].push_back(` `                        ``{ nextNodeLabel, 1 });` `            ``}` `        ``}` `    ``}`   `    ``// Applying dijkstra's algorithm` `    ``return` `zeroOneBFS(adj, 0,` `                      ``(N - 1) * N + M - 1, N, M);` `}`   `// Driver code` `int` `main()` `{` `    ``vector > mat = { { 2, 2, 1 },` `                                 ``{ 4, 2, 3 },` `                                 ``{ 4, 3, 2 } };`   `    ``// Function call` `    ``cout << MinModifications(mat);`   `    ``return` `0;` `}`

## Python3

 `# Python3 program to find minimum` `# possible changes required` `# in the matrix` `from` `collections ``import` `deque`   `# Function to find next possible node` `def` `nextNode(x, y, ``dir``, N, M):` `    ``if` `(``dir` `=``=` `1``):` `        ``y ``-``=` `1` `    ``elif` `(``dir` `=``=` `2``):` `        ``y ``+``=` `1` `    ``elif` `(``dir` `=``=` `3``):` `        ``x ``-``=` `1` `    ``else``:` `        ``x ``+``=` `1`   `    ``# If node is out of matrix` `    ``if` `(``not` `(x >``=` `0` `and` `x < N ``and` `y >``=` `0` `and` `y < M)):` `        ``return` `-``1` `    ``else``:` `        ``return` `(x ``*` `N ``+` `y)`   `# Prints shortest distance` `# from given source to` `# every other vertex` `def` `zeroOneBFS(adj, src, dest, N, M):` `  `  `    ``# Initialize distances` `    ``# from given source` `    ``dist ``=` `[``10``*``*``8``] ``*``(N ``*` `M)`   `    ``# Double ended queue to do BFS.` `    ``Q ``=` `deque()` `    ``dist[src] ``=` `0` `    ``Q.append(src)`   `    ``while` `(``len``(Q) > ``0``):` `        ``v ``=` `Q.popleft()`   `        ``for` `i ``in` `adj[v]:` `          `  `            ``# print(i)` `            ``# Checking for the optimal distance` `            ``if` `(dist[i[``0``]] > dist[v] ``+` `i[``1``]):` `                ``dist[i[``0``]] ``=` `dist[v] ``+` `i[``1``]` `                `  `                ``# Put 0 weight edges to front` `                ``# and 1 weight edges to back` `                ``# so that vertices are processed` `                ``# in increasing order of weights.` `                ``if` `(i[``1``] ``=``=` `0``):` `                    ``Q.appendleft(i[``0``])` `                ``else``:` `                    ``Q.append(i[``0``])`   `    ``# Shortest distance to` `    ``# reach destination` `    ``return` `dist[dest]`   `# Function to find minimum possible` `# changes required in the matrix` `def` `MinModifications(mat):` `    ``N, M ``=` `len``(mat), ``len``(mat[``0``])`   `    ``# Converting given matrix to a graph` `    ``adj ``=` `[[] ``for` `i ``in` `range``(N ``*` `M)]`   `    ``for` `i ``in` `range``(N):` `        ``for` `j ``in` `range``(M):` `          `  `            ``# Each cell is a node` `            ``# with label i*N + j` `            ``for` `dir` `in` `range``(``1``, ``5``):` `              `  `                ``# Label of node if we` `                ``# move in direction dir` `                ``nextNodeLabel ``=` `nextNode(i, j, ``dir``, N, M)`   `                ``# If invalid(out of matrix)` `                ``if` `(nextNodeLabel ``=``=` `-``1``):` `                    ``continue`   `                ``# If direction is same as mat[i][j]` `                ``if` `(``dir` `=``=` `mat[i][j]):` `                    ``adj[i ``*` `N ``+` `j].append([nextNodeLabel, ``0``])` `                ``else``:` `                    ``adj[i ``*` `N ``+` `j].append([nextNodeLabel, ``1``])`   `    ``# Applying dijkstra's algorithm` `    ``return` `zeroOneBFS(adj, ``0``, (N ``-` `1``) ``*` `N ``+` `M ``-` `1``, N, M)`   `# Driver code` `if` `__name__ ``=``=` `'__main__'``:` `    ``mat ``=` `[ [ ``2``, ``2``, ``1` `],` `             ``[ ``4``, ``2``, ``3` `],` `             ``[ ``4``, ``3``, ``2` `] ]`   `    ``# Function call` `    ``print` `(MinModifications(mat))`   `# This code is contributed by mohit kumar 29.`

## Javascript

 ``

Output:

`2`

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

My Personal Notes arrow_drop_up
Recommended Articles
Page :