📜  达到矩阵任意边界的最小步长套装1

📅  最后修改于: 2021-04-24 16:45:50             🧑  作者: Mango

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

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

例子:

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 

方法:可以使用动态编程方法解决问题。下面给出的是解决上述问题的算法。

  • 查找矩阵中具有“ 2”的位置。
  • 初始化两个大小与矩阵相同的二维数组。 dp [] []存储达到任何索引i,j和vis [] []标记的最小步数,如果之前或之前未访问过任何特定的i,j位置。
  • 调用具有基本情况的递归函数,如下所示:
    1. 如果在任意点处的遍历到达任何边界边,则返回0。
    2. 如果点位置n,m先前已存储了最少的步数,则返回dp [n] [m]。
  • 从位置n,m进行所有可能的四步移动,再次调用递归。仅当mat [n] [m]为0并且之前未访问过该位置时,才可以移动。
  • 存储最少的四个动作。
  • 如果递归返回的任何小于1e9的值(我们已将其存储为最大值),则有一个答案,否则它没有任何答案。

下面是上述方法的实现:

C++
// C++ program to find Minimum steps
// to reach any of the boundary
// edges of a matrix
#include 
using namespace std;
#define r 4
#define col 5
  
// Function to find out minimum steps
int findMinSteps(int mat[r][col], int n, int m, int dp[r][col], bool vis[r][col])
{
    // boundary edges reached
    if (n == 0 || m == 0 || n == (r - 1) || m == (col - 1)) {
        return 0;
    }
  
    // already had a route through this
    // point, hence no need to re-visit
    if (dp[n][m] != -1)
        return dp[n][m];
  
    // visiting a position
    vis[n][m] = true;
  
    int ans1, ans2, ans3, ans4;
  
    ans1 = ans2 = ans3 = ans4 = 1e9;
  
    // vertically up
    if (mat[n - 1][m] == 0) {
        if (!vis[n - 1][m])
            ans1 = 1 + findMinSteps(mat, n - 1, m, dp, vis);
    }
  
    // horizontally right
    if (mat[n][m + 1] == 0) {
        if (!vis[n][m + 1])
            ans2 = 1 + findMinSteps(mat, n, m + 1, dp, vis);
    }
  
    // horizontally left
    if (mat[n][m - 1] == 0) {
        if (!vis[n][m - 1])
            ans3 = 1 + findMinSteps(mat, n, m - 1, dp, vis);
    }
  
    // vertically down
    if (mat[n + 1][m] == 0) {
        if (!vis[n + 1][m])
            ans4 = 1 + findMinSteps(mat, n + 1, m, dp, vis);
    }
  
    // minimum of every path
    dp[n][m] = min(ans1, min(ans2, min(ans3, ans4)));
    return dp[n][m];
}
  
// Function that returns the minimum steps
int minimumSteps(int mat[r][col], int n, int m)
{
    // index to store the location at
    // which you are standing
    int twox = -1;
    int twoy = -1;
  
    // find '2' in the matrix
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (mat[i][j] == 2) {
                twox = i;
                twoy = j;
                break;
            }
        }
        if (twox != -1)
            break;
    }
  
    // Initialize dp matrix with -1
    int dp[r][col];
    memset(dp, -1, sizeof dp);
  
    // Initialize vis matrix with false
    bool vis[r][col];
    memset(vis, false, sizeof vis);
  
    // Call function to find out minimum steps
    // using memoization and recursion
    int res = findMinSteps(mat, twox, twoy, dp, vis);
  
    // if not possible
    if (res >= 1e9)
        return -1;
    else
        return res;
}
  
// Driver Code
int main()
{
    int mat[r][col] = { { 1, 1, 1, 0, 1 },
                      { 1, 0, 2, 0, 1 },
                      { 0, 0, 1, 0, 1 },
                      { 1, 0, 1, 1, 0 } };
  
    cout << minimumSteps(mat, r, col);
}


Java
// Java program to find Minimum steps
// to reach any of the boundary
// edges of a matrix
class Solution
{
static final int  r=4,c=5;
  
// Function to find out minimum steps
static int findMinSteps(int mat[][], int n, int m, int dp[][], boolean vis[][])
{
    // boundary edges reached
    if (n == 0 || m == 0 || n == (r - 1) || m == (c - 1)) {
        return 0;
    }
   
    // already had a route through this
    // point, hence no need to re-visit
    if (dp[n][m] != -1)
        return dp[n][m];
   
    // visiting a position
    vis[n][m] = true;
   
    int ans1, ans2, ans3, ans4;
   
    ans1 = ans2 = ans3 = ans4 = (int)1e9;
   
    // vertically up
    if (mat[n - 1][m] == 0) {
        if (!vis[n - 1][m])
            ans1 = 1 + findMinSteps(mat, n - 1, m, dp, vis);
    }
   
    // horizontally right
    if (mat[n][m + 1] == 0) {
        if (!vis[n][m + 1])
            ans2 = 1 + findMinSteps(mat, n, m + 1, dp, vis);
    }
   
    // horizontally left
    if (mat[n][m - 1] == 0) {
        if (!vis[n][m - 1])
            ans3 = 1 + findMinSteps(mat, n, m - 1, dp, vis);
    }
   
    // vertically down
    if (mat[n + 1][m] == 0) {
        if (!vis[n + 1][m])
            ans4 = 1 + findMinSteps(mat, n + 1, m, dp, vis);
    }
   
    // minimum of every path
    dp[n][m] = Math.min(ans1, Math.min(ans2, Math.min(ans3, ans4)));
    return dp[n][m];
}
   
// Function that returns the minimum steps
static int minimumSteps(int mat[][], int n, int m)
{
    // index to store the location at
    // which you are standing
    int twox = -1;
    int twoy = -1;
   
    // find '2' in the matrix
    for (int i = 0; i < n; i++) {
        for (int j = 0; j < m; j++) {
            if (mat[i][j] == 2) {
                twox = i;
                twoy = j;
                break;
            }
        }
        if (twox != -1)
            break;
    }
   
    // Initialize dp matrix with -1
    int dp[][]=new int[r][r];
    for(int j=0;j= 1e9)
        return -1;
    else
        return res;
}
   
// Driver Code
public static void main(String args[])
{
    int mat[][] = { { 1, 1, 1, 0, 1 },
                      { 1, 0, 2, 0, 1 },
                      { 0, 0, 1, 0, 1 },
                      { 1, 0, 1, 1, 0 } };
   
    System.out.println( minimumSteps(mat, r, c));
}
}
//contributed by Arnab Kundu


Python
# Python program to find Minimum steps
# to reach any of the boundary
# edges of a matrix
  
r=4
col=5
   
# Function to find out minimum steps
def findMinSteps(mat, n, m, dp,vis):
  
    # boundary edges reached
    if (n == 0 or m == 0 or n == (r - 1) or m == (col - 1)):
        return 0
      
   
    # already had a route through this
    # point, hence no need to re-visit
    if (dp[n][m] != -1):
        return dp[n][m]
   
    # visiting a position
    vis[n][m] = True
   
    ans1, ans2, ans3, ans4=10**9,10**9,10**9,10**9
  
   
    # vertically up
    if (mat[n - 1][m] == 0):
        if (vis[n - 1][m]==False):
            ans1 = 1 + findMinSteps(mat, n - 1, m, dp, vis)
      
   
    # horizontally right
    if (mat[n][m + 1] == 0):
        if (vis[n][m + 1]==False):
            ans2 = 1 + findMinSteps(mat, n, m + 1, dp, vis)
      
   
    # horizontally left
    if (mat[n][m - 1] == 0):
        if (vis[n][m - 1]==False):
            ans3 = 1 + findMinSteps(mat, n, m - 1, dp, vis)
      
   
    # vertically down
    if (mat[n + 1][m] == 0):
        if (vis[n + 1][m]==False):
            ans4 = 1 + findMinSteps(mat, n + 1, m, dp, vis)
      
   
    # minimum of every path
    dp[n][m] = min(ans1, min(ans2, min(ans3, ans4)))
    return dp[n][m]
  
   
# Function that returns the minimum steps
def minimumSteps(mat, n, m):
  
    # index to store the location at
    # which you are standing
    twox = -1
    twoy = -1
   
    # find '2' in the matrix
    for i in range(n): 
        for j in range(m): 
            if (mat[i][j] == 2):
                twox = i
                twoy = j
                break
              
          
        if (twox != -1):
            break
      
   
    # Initialize dp matrix with -1
    dp=[[-1 for i in range(col)] for i in range(r)]
      
   
    # Initialize vis matrix with false
    vis=[[False for i in range(col)] for i in range(r)]
      
   
    # Call function to find out minimum steps
    # using memoization and recursion
    res = findMinSteps(mat, twox, twoy, dp, vis)
   
    # if not possible
    if (res >= 10**9):
        return -1
    else:
        return res
  
   
# Driver Code
  
  
mat= [ [ 1, 1, 1, 0, 1 ],
      [ 1, 0, 2, 0, 1 ],
      [ 0, 0, 1, 0, 1 ],
      [ 1, 0, 1, 1, 0 ] ]
  
print(minimumSteps(mat, r, col))
  
#this is contributed by Mohit kumar 29


C#
// C# program to find Minimum steps 
// to reach any of the boundary 
// edges of a matrix
  
using System;
  
class Solution 
{ 
static int r=4,c=5; 
  
    // Function to find out minimum steps 
    static int findMinSteps(int [,]mat, int n, int m, int [,]dp, bool [,]vis) 
    { 
        // boundary edges reached 
        if (n == 0 || m == 0 || n == (r - 1) || m == (c - 1)) { 
            return 0; 
        } 
      
        // already had a route through this 
        // point, hence no need to re-visit 
        if (dp[n,m] != -1) 
            return dp[n,m]; 
      
        // visiting a position 
        vis[n,m] = true; 
      
        int ans1, ans2, ans3, ans4; 
      
        ans1 = ans2 = ans3 = ans4 = (int)1e9; 
      
        // vertically up 
        if (mat[n - 1,m] == 0) { 
            if (!vis[n - 1,m]) 
                ans1 = 1 + findMinSteps(mat, n - 1, m, dp, vis); 
        } 
      
        // horizontally right 
        if (mat[n,m + 1] == 0) { 
            if (!vis[n,m + 1]) 
                ans2 = 1 + findMinSteps(mat, n, m + 1, dp, vis); 
        } 
      
        // horizontally left 
        if (mat[n,m - 1] == 0) { 
            if (!vis[n,m - 1]) 
                ans3 = 1 + findMinSteps(mat, n, m - 1, dp, vis); 
        } 
      
        // vertically down 
        if (mat[n + 1,m] == 0) { 
            if (!vis[n + 1,m]) 
                ans4 = 1 + findMinSteps(mat, n + 1, m, dp, vis); 
        } 
      
        // minimum of every path 
        dp[n,m] = Math.Min(ans1, Math.Min(ans2, Math.Min(ans3, ans4))); 
        return dp[n,m]; 
    } 
      
    // Function that returns the minimum steps 
    static int minimumSteps(int [,]mat, int n, int m) 
    { 
        // index to store the location at 
        // which you are standing 
        int twox = -1; 
        int twoy = -1; 
      
        // find '2' in the matrix 
        for (int i = 0; i < n; i++) { 
            for (int j = 0; j < m; j++) { 
                if (mat[i,j] == 2) { 
                    twox = i; 
                    twoy = j; 
                    break; 
                } 
            } 
            if (twox != -1) 
                break; 
        } 
      
        // Initialize dp matrix with -1 
        int [,]dp = new int[r,r]; 
        for(int j=0;j= 1e9) 
            return -1; 
        else
            return res; 
    } 
      
    // Driver Code 
    public static void Main() 
    { 
        int [,]mat = { { 1, 1, 1, 0, 1 }, 
                        { 1, 0, 2, 0, 1 }, 
                        { 0, 0, 1, 0, 1 }, 
                        { 1, 0, 1, 1, 0 }, }; 
      
        Console.WriteLine(minimumSteps(mat, r, c)); 
    } 
    // This code is contributed by Ryuga
  
}


输出:
2

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

达到矩阵任意边界的最小步长套装2