Open In App

Shortest XY distance in Grid

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:

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);

Output
Minimum distance from 'X' to 'Y': 1










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


Article Tags :