📜  到达矩阵的任何边界边的最小步长 |组 2

📅  最后修改于: 2022-05-13 01:57:00.753000             🧑  作者: Mango

到达矩阵的任何边界边的最小步长 |组 2

给定一个 NXM 矩阵,其中 a i, j = 1 表示该单元格不为空,a i, j = 0 表示该单元格为空,而 a i, j = 2 表示您正站在该单元格处。您可以垂直向上或向下以及水平向左或向右移动到任何空单元格。任务是找到到达矩阵任何边界边的最少步数。如果不可能到达任何边界边缘,则打印 -1。

注意:整个矩阵中将只有一个值为 2 的单元格。

如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程学生竞争性编程现场课程。

例子:



Input: matrix[] = {1, 1, 1, 0, 1}
                  {1, 0, 2, 0, 1} 
                  {0, 0, 1, 0, 1}
                  {1, 0, 1, 1, 0} 
Output: 2
Move to the right and then move 
upwards to reach the nearest boundary
edge. 

Input: matrix[] = {1, 1, 1, 1, 1}
                  {1, 0, 2, 0, 1} 
                  {1, 0, 1, 0, 1}
                  {1, 1, 1, 1, 1}
Output: -1 

方法:该问题已在 Set-1 中使用动态规划解决。在本文中,我们将讨论一种使用 BFS 的方法。下面给出解决上述问题的步骤。

  • 找到矩阵中“2”的索引。
  • 检查此索引是否为边界边,如果是,则不需要移动。
  • 将 '2' 的索引 x 和索引 y 插入队列中,移动为 0。
  • 使用二维 vis 数组来标记矩阵中的访问位置。
  • 迭代直到队列为空或我们到达任何边界边缘。
  • 获取队列中的前元素(x, y, val =moves) 并将 vis[x][y] 标记为已访问。做所有可能的移动(向右、向左、向上和向下)。
  • 将 val+1 及其所有有效移动的索引重新插入队列。
  • 如果 x 和 y 成为边界边,则随时返回 val。
  • 如果所有的动作都完成了,并且队列是空的,那么这是不可能的,因此返回-1。

下面是上述方法的实现:

CPP
// C++ program to find Minimum steps
// to reach any of the boundary
// edges of a matrix
#include 
using namespace std;
#define r 4
#define c 5
  
// Function to check validity
bool check(int i, int j, int n, int m, int mat[r])
{
    if (i >= 0 && i < n && j >= 0 && j < m) {
        if (mat[i][j] == 0)
            return true;
    }
    return false;
}
  
// Function to find out minimum steps
int findMinSteps(int mat[r], int n, int m)
{
  
    int indx, indy;
    indx = indy = -1;
  
    // Find index of only 2 in matrix
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (mat[i][j] == 2) {
                indx = i, indy = j;
                break;
            }
        }
        if (indx != -1)
            break;
    }
  
    // Push elements in the queue
    queue > > q;
  
    // Push the position 2 with moves as 0
    q.push(make_pair(0, make_pair(indx, indy)));
  
    // If already at boundary edge
    if (check(indx, indy, n, m, mat))
        return 0;
  
    // Marks the visit
    bool vis[r];
    memset(vis, 0, sizeof vis);
  
    // Iterate in the queue
    while (!q.empty()) {
        // Get the front of the queue
        auto it = q.front();
  
        // Pop the first element from the queue
        q.pop();
  
        // Get the position
        int x = it.second.first;
        int y = it.second.second;
  
        // Moves
        int val = it.first;
  
        // If a boundary edge
        if (x == 0 || x == (n - 1) || y == 0 || y == (m - 1)) {
            return val;
        }
  
        // Marks the visited array
        vis[x][y] = 1;
  
        // If a move is possible
        if (check(x - 1, y, n, m, mat)) {
  
            // If not visited previously
            if (!vis[x - 1][y])
                q.push(make_pair(val + 1, make_pair(x - 1, y)));
        }
  
        // If a move is possible
        if (check(x + 1, y, n, m, mat)) {
  
            // If not visited previously
            if (!vis[x + 1][y])
                q.push(make_pair(val + 1, make_pair(x + 1, y)));
        }
  
        // If a move is possible
        if (check(x, y + 1, n, m, mat)) {
  
            // If not visited previously
            if (!vis[x][y + 1])
                q.push(make_pair(val + 1, make_pair(x, y + 1)));
        }
  
        // If a move is possible
        if (check(x, y - 1, n, m, mat)) {
  
            // If not visited previously
            if (!vis[x][y - 1])
                q.push(make_pair(val + 1, make_pair(x, y - 1)));
        }
    }
  
    return -1;
}
  
// Driver Code
int main()
{
    int mat[r] = { { 1, 1, 1, 0, 1 },
                      { 1, 0, 2, 0, 1 },
                      { 0, 0, 1, 0, 1 },
                      { 1, 0, 1, 1, 0 } };
  
    cout << findMinSteps(mat, r, c);
}


Python3
# Python3 program to find Minimum steps
# to reach any of the boundary
# edges of a matrix
from collections import deque
r = 4
c = 5
  
# Function to check validity
def check(i, j, n, m, mat):
  
    if (i >= 0 and i < n and j >= 0 and j < m):
        if (mat[i][j] == 0):
            return True
  
    return False
  
# Function to find out minimum steps
def findMinSteps(mat, n, m):
  
    indx = indy = -1;
  
    # Find index of only 2 in matrix
    for i in range(n):
        for j in range(m):
            if (mat[i][j] == 2):
                indx = i
                indy = j
                break
  
        if (indx != -1):
            break
  
    # Push elements in the queue
    q = deque()
  
    # Push the position 2 with moves as 0
    q.append([0, indx, indy])
  
    # If already at boundary edge
    if (check(indx, indy, n, m, mat)):
        return 0
  
    # Marks the visit
    vis=[ [0 for i in range(r)]for i in range(r)]
  
    # Iterate in the queue
    while len(q) > 0:
          
        # Get the front of the queue
        it = q.popleft()
  
        #Pop the first element from the queue
  
        # Get the position
        x = it[1]
        y = it[2]
  
        # Moves
        val = it[0]
  
        # If a boundary edge
        if (x == 0 or x == (n - 1) or y == 0 or y == (m - 1)):
            return val
  
  
        # Marks the visited array
        vis[x][y] = 1
  
        # If a move is possible
        if (check(x - 1, y, n, m, mat)):
  
            # If not visited previously
            if (not vis[x - 1][y]):
                q.append([val + 1, x - 1, y])
  
        # If a move is possible
        if (check(x + 1, y, n, m, mat)):
  
            # If not visited previously
            if (not vis[x + 1][y]):
                q.append([val + 1, x + 1, y])
  
        # If a move is possible
        if (check(x, y + 1, n, m, mat)):
  
            # If not visited previously
            if (not vis[x][y + 1]):
                q.append([val + 1, x, y + 1])
  
        # If a move is possible
        if (check(x, y - 1, n, m, mat)):
  
            # If not visited previously
            if (not vis[x][y - 1]):
                q.append([val + 1, x, y - 1])
  
    return -1
  
# Driver Code
mat = [[1, 1, 1, 0, 1 ],
       [1, 0, 2, 0, 1 ],
       [0, 0, 1, 0, 1 ],
       [1, 0, 1, 1, 0 ] ];
  
print(findMinSteps(mat, r, c))
  
# This code is contributed by mohit kumar 29


输出:
2

时间复杂度: O(N^2)
辅助空间: O(N^2)