Given an N*M grid of characters ‘O’, ‘X’, and ‘Y’. Find the minimum Manhattan distance between an X and a Y.
Manhattan Distance : | row_index_x – row_index_y | + | column_index_x – column_index_y |
Examples:
Input: N = 4, M = 4
grid[][] = {{X, O, O, O}
{O, Y, O, Y}
{X, X, O, O}
{O, Y, O, O}}
Output: 1
Explanation:
{{X, O, O, O}
{O, Y, O, Y}
{X, X, O, O}
{O, Y, O, O}}
The shortest X-Y distance in the grid is 1. One possible such X and Y are marked in bold in the above grid.Input: N = 3, M = 3
grid[][] = {{X, X, O}
{O, O, Y}
{Y, O, O}}Output: 2
Explanation:
{{X, X, O}
{O, O, Y}
{Y, O, O}}
The shortest X-Y distance in the grid is 2. One possible such X and Y are marked in bold in the above grid.
Approach: To solve the problem follow the below idea:
The idea is to use dynamic programming(to prevent computation of min distance again and again) to compute the shortest distance between every cell in the grid and the nearest cell with value ‘X’. we initializes the distance to a very large value for every cell except for the ‘X’ cells, which have a distance of 0. It then computes the distance from each cell to its top and left neighbors, and then from each cell to its bottom and right neighbors. Finally, we finds the cell with value ‘Y’ (target) with the shortest distance to an ‘X’ cell.
Step-by-step approach:
- Create a 2D array called dist with dimensions N x M.
- Initialize all elements of dist to a very large value (in this case, 1000000000).
-
Loop through each element of the grid and check if it is an ‘X’ character or not.
- If it is an ‘X’ character, set the corresponding element in dist to 0.
- If it is not an ‘X’ character, calculate the distance to the top and left elements using dist[i-1][j] and dist[i][j-1], respectively. Take the minimum of the two values and add 1 to get the distance to the current element.
-
Loop through each element of the grid again, but this time, check the ,perform step 3 for calculating the relative distance from X .
- Calculate the distances to the bottom and right elements using dist[i+1][j] and dist[i][j+1], respectively. Take the minimum of the two values and add 1 to get the distance to the current element.
- Update the corresponding element in dist if this calculated distance is smaller than its current value.
-
Run a Loop through each element of the grid one final time and find the minimum value of dist for all ‘Y’ characters in the grid.
- keep storing the min distance while traversing the dist array and storing it in ans.
- Return ans.
Below is the implementation of the above approach:
// C++ code for the above approach: #include <bits/stdc++.h> using namespace std;
int shortestXYDist(vector<vector< char > > grid, int N, int M)
{ // Create a 2D array to store distances.
// Initialize with a large value.
int dist[N][M];
for ( int i = 0; i < N; i++) {
// Initialize with a large value
// (indicating infinity).
for ( int j = 0; j < M; j++) {
dist[i][j] = 1e9;
}
}
// Check top and left directions
// for 'X' cells.
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < M; j++) {
if (grid[i][j] == 'X' )
// Set distance to 0 for 'X' cells.
dist[i][j] = 0;
else {
if (i > 0)
// Check above cell.
dist[i][j] = min(dist[i][j],
dist[i - 1][j] + 1);
if (j > 0)
// Check left cell.
dist[i][j] = min(dist[i][j],
dist[i][j - 1] + 1);
}
}
}
// Check bottom and right directions
// for 'X' cells.
for ( int i = N - 1; i >= 0; i--) {
for ( int j = M - 1; j >= 0; j--) {
if (grid[i][j] == 'X' )
// Set distance to 0 for 'X' cells.
dist[i][j] = 0;
else {
if (i < N - 1)
dist[i][j]
= min(dist[i][j],
dist[i + 1][j]
+ 1); // Check below cell.
if (j < M - 1)
// Check right cell.
dist[i][j] = min(dist[i][j],
dist[i][j + 1] + 1);
}
}
}
// Initialize the minimum distance with a
// large value.
int ans = 1e9;
// Find the minimum distance to 'Y' cells.
for ( int i = 0; i < N; i++) {
for ( int j = 0; j < M; j++) {
if (grid[i][j] == 'Y' )
// Update the minimum
// distance.
ans = min(ans, dist[i][j]);
}
}
// Return the minimum distance.
return ans;
} // Drivers code int main()
{ int N = 4;
int M = 4;
vector<vector< char > > grid = { { 'X' , 'O' , 'O' , 'O' },
{ 'O' , 'Y' , 'O' , 'Y' },
{ 'X' , 'X' , 'O' , 'O' },
{ 'O' , 'Y' , 'O' , 'O' } };
int minDistance = shortestXYDist(grid, N, M);
// Function call
cout << "Minimum distance from 'X' to 'Y' : "
<< minDistance << endl;
return 0;
} |
import java.util.Arrays;
public class ShortestDistance {
public static int shortestXYDist( char [][] grid, int N,
int M)
{
// Create a 2D array to store distances.
// Initialize with a large value.
int [][] dist = new int [N][M];
for ( int i = 0 ; i < N; i++) {
// Initialize with a large value (indicating
// infinity).
Arrays.fill(dist[i], 1_000_000_000);
}
// Check top and left directions for 'X' cells.
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < M; j++) {
if (grid[i][j] == 'X' ) {
// Set distance to 0 for 'X' cells.
dist[i][j] = 0 ;
}
else {
if (i > 0 ) {
// Check above cell.
dist[i][j] = Math.min(
dist[i][j], dist[i - 1 ][j] + 1 );
}
if (j > 0 ) {
// Check left cell.
dist[i][j] = Math.min(
dist[i][j], dist[i][j - 1 ] + 1 );
}
}
}
}
// Check bottom and right directions for 'X' cells.
for ( int i = N - 1 ; i >= 0 ; i--) {
for ( int j = M - 1 ; j >= 0 ; j--) {
if (grid[i][j] == 'X' ) {
// Set distance to 0 for 'X' cells.
dist[i][j] = 0 ;
}
else {
if (i < N - 1 ) {
// Check below cell.
dist[i][j] = Math.min(
dist[i][j], dist[i + 1 ][j] + 1 );
}
if (j < M - 1 ) {
// Check right cell.
dist[i][j] = Math.min(
dist[i][j], dist[i][j + 1 ] + 1 );
}
}
}
}
// Initialize the minimum distance with a large
// value.
int ans = 1_000_000_000;
// Find the minimum distance to 'Y' cells.
for ( int i = 0 ; i < N; i++) {
for ( int j = 0 ; j < M; j++) {
if (grid[i][j] == 'Y' ) {
// Update the minimum distance.
ans = Math.min(ans, dist[i][j]);
}
}
}
// Return the minimum distance.
return ans;
}
// Drivers code
public static void main(String[] args)
{
int N = 4 ;
int M = 4 ;
char [][] grid = { { 'X' , 'O' , 'O' , 'O' },
{ 'O' , 'Y' , 'O' , 'Y' },
{ 'X' , 'X' , 'O' , 'O' },
{ 'O' , 'Y' , 'O' , 'O' } };
int minDistance = shortestXYDist(grid, N, M);
// Function call
System.out.println(
"Minimum distance from 'X' to 'Y': "
+ minDistance);
}
} |
def shortestXYDist(grid):
# Get the dimensions of the grid
N = len (grid)
M = len (grid[ 0 ])
# Create a 2D array to store distances, initialize with a large value
dist = [[ float ( 'inf' ) for _ in range (M)] for _ in range (N)]
# Check top and left directions for 'X' cells
for i in range (N):
for j in range (M):
if grid[i][j] = = 'X' :
# Set distance to 0 for 'X' cells
dist[i][j] = 0
else :
if i > 0 :
# Check above cell
dist[i][j] = min (dist[i][j], dist[i - 1 ][j] + 1 )
if j > 0 :
# Check left cell
dist[i][j] = min (dist[i][j], dist[i][j - 1 ] + 1 )
# Check bottom and right directions for 'X' cells
for i in range (N - 1 , - 1 , - 1 ):
for j in range (M - 1 , - 1 , - 1 ):
if grid[i][j] = = 'X' :
# Set distance to 0 for 'X' cells
dist[i][j] = 0
else :
if i < N - 1 :
# Check below cell
dist[i][j] = min (dist[i][j], dist[i + 1 ][j] + 1 )
if j < M - 1 :
# Check right cell
dist[i][j] = min (dist[i][j], dist[i][j + 1 ] + 1 )
# Initialize the minimum distance with a large value
ans = float ( 'inf' )
# Find the minimum distance to 'Y' cells
for i in range (N):
for j in range (M):
if grid[i][j] = = 'Y' :
# Update the minimum distance
ans = min (ans, dist[i][j])
# Return the minimum distance
return ans
# Driver code grid = [
[ 'X' , 'O' , 'O' , 'O' ],
[ 'O' , 'Y' , 'O' , 'Y' ],
[ 'X' , 'X' , 'O' , 'O' ],
[ 'O' , 'Y' , 'O' , 'O' ]
] minDistance = shortestXYDist(grid)
# Function call print ( "Minimum distance from 'X' to 'Y':" , minDistance)
|
using System;
class Program
{ static int ShortestXYDist( char [][] grid, int N, int M)
{
// Create a 2D array to store distances.
// Initialize with the maximum value for an int.
int [,] dist = new int [N, M];
for ( int i = 0; i < N; i++)
{
// Initialize with the maximum value for an int
// (indicating infinity).
for ( int j = 0; j < M; j++)
{
dist[i, j] = int .MaxValue;
}
}
// Check top and left directions
// for 'X' cells.
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < M; j++)
{
if (grid[i][j] == 'X' )
{
// Set distance to 0 for 'X' cells.
dist[i, j] = 0;
}
else
{
if (i > 0)
{
// Check above cell.
dist[i, j] = Math.Min(dist[i, j], dist[i - 1, j] + 1);
}
if (j > 0)
{
// Check left cell.
dist[i, j] = Math.Min(dist[i, j], dist[i, j - 1] + 1);
}
}
}
}
// Check bottom and right directions
// for 'X' cells.
for ( int i = N - 1; i >= 0; i--)
{
for ( int j = M - 1; j >= 0; j--)
{
if (grid[i][j] == 'X' )
{
// Set distance to 0 for 'X' cells.
dist[i, j] = 0;
}
else
{
if (i < N - 1)
{
// Check below cell.
dist[i, j] = Math.Min(dist[i, j], dist[i + 1, j] + 1);
}
if (j < M - 1)
{
// Check right cell.
dist[i, j] = Math.Min(dist[i, j], dist[i, j + 1] + 1);
}
}
}
}
// Initialize the minimum distance with the maximum value for an int.
int ans = int .MaxValue;
// Find the minimum distance to 'Y' cells.
for ( int i = 0; i < N; i++)
{
for ( int j = 0; j < M; j++)
{
if (grid[i][j] == 'Y' )
{
// Update the minimum distance.
ans = Math.Min(ans, dist[i, j]);
}
}
}
// Return the minimum distance.
return ans == int .MaxValue ? -1 : ans;
}
// Driver code
static void Main()
{
int N = 4;
int M = 4;
char [][] grid = new char [][]
{
new char [] { 'X' , 'O' , 'O' , 'O' },
new char [] { 'O' , 'Y' , 'O' , 'Y' },
new char [] { 'X' , 'X' , 'O' , 'O' },
new char [] { 'O' , 'Y' , 'O' , 'O' }
};
int minDistance = ShortestXYDist(grid, N, M);
// Function call
Console.WriteLine( "Minimum distance from 'X' to 'Y': " +
(minDistance == -1 ? "Not reachable" : minDistance.ToString()));
}
} |
function shortestXYDist(grid) {
// Get the dimensions of the grid
const N = grid.length;
const M = grid[0].length;
// Create a 2D array to store distances, initialize with a large value
const dist = Array.from({ length: N }, () => Array(M).fill(Number.POSITIVE_INFINITY));
// Check top and left directions for 'X' cells
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (grid[i][j] === 'X' ) {
// Set distance to 0 for 'X' cells
dist[i][j] = 0;
} else {
if (i > 0) {
// Check above cell
dist[i][j] = Math.min(dist[i][j], dist[i - 1][j] + 1);
}
if (j > 0) {
// Check left cell
dist[i][j] = Math.min(dist[i][j], dist[i][j - 1] + 1);
}
}
}
}
// Check bottom and right directions for 'X' cells
for (let i = N - 1; i >= 0; i--) {
for (let j = M - 1; j >= 0; j--) {
if (grid[i][j] === 'X' ) {
// Set distance to 0 for 'X' cells
dist[i][j] = 0;
} else {
if (i < N - 1) {
// Check below cell
dist[i][j] = Math.min(dist[i][j], dist[i + 1][j] + 1);
}
if (j < M - 1) {
// Check right cell
dist[i][j] = Math.min(dist[i][j], dist[i][j + 1] + 1);
}
}
}
}
// Initialize the minimum distance with a large value
let ans = Number.POSITIVE_INFINITY;
// Find the minimum distance to 'Y' cells
for (let i = 0; i < N; i++) {
for (let j = 0; j < M; j++) {
if (grid[i][j] === 'Y' ) {
// Update the minimum distance
ans = Math.min(ans, dist[i][j]);
}
}
}
// Return the minimum distance
return ans;
} // Driver code const grid = [ [ 'X' , 'O' , 'O' , 'O' ],
[ 'O' , 'Y' , 'O' , 'Y' ],
[ 'X' , 'X' , 'O' , 'O' ],
[ 'O' , 'Y' , 'O' , 'O' ]
]; const minDistance = shortestXYDist(grid); // Function call console.log( "Minimum distance from 'X' to 'Y':" , minDistance);
|
Minimum distance from 'X' to 'Y': 1
Time Complexity: O(N*M)
Auxiliary Space: O(N*M)