Open In App

Shortest XY distance in Grid

Last Updated : 31 Dec, 2023
Improve
Improve
Like Article
Like
Save
Share
Report

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++




// 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;
}


Java




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


Python3




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)


C#




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


Javascript




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)



Like Article
Suggest improvement
Share your thoughts in the comments

Similar Reads