📌  相关文章
📜  检查给定矩阵中是否存在从开始到结束单元格的路径,障碍物最多 K 次移动

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

检查给定矩阵中是否存在从开始到结束单元格的路径,障碍物最多 K 次移动

给定一个正整数K和一个由字符'.'组成的维度为N * M的矩阵网格。和'#' ,其中'.'表示未阻塞的单元格, '#'表示阻塞的单元格,任务是检查是否可以通过最多K次移动的未阻塞单元格从矩阵的左上角单元格到达网格的右下角,使得向右或向下移动到其相邻的单元格需要移动一次。

例子:

方法:给定的问题可以在动态规划的帮助下使用制表方法来解决。它可以通过使用类似于本文中讨论的方法预先计算从左上角移动到右下角单元格所需的最小移动次数来解决。可以看出,如果dp[i][j]表示从(0, 0)到达单元格(i, j)的最小移动次数,则 DP 关系可以表述为:

此后,如果最小移动次数最多为K ,则打印“是”,否则打印“否”。

下面是上述方法的实现:

C++
// C++ implementation for the above approach
#include "bits/stdc++.h"
using namespace std;
 
// Function to check if it is possible
// to reach the bottom right of the grid
// from top left using atmost K moves
string canReach(vector >& grid, int K)
{
    int N = grid.size();
    int M = grid[0].size();
 
    // Stores the DP states
    vector > dp(
        N, vector(M, INT_MAX));
     
      // if first cell or last cell is blocked then
    // not possible
    if(grid[0][0] != '.' || grid[N - 1][M - 1] != '.')
      return "No";
   
    // Initial condition
    dp[0][0] = 0;
 
    // Initializing the DP table
    // in 1st row
    for (int i = 1; i < M; i++) {
        if (grid[0][i] == '.') {
            dp[0][i] = 1 + dp[0][i - 1];
        }
        else
            break;
    }
 
    // Initializing the DP table
    // in 1st column
    for (int i = 1; i < N; i++) {
        if (grid[i][0] == '.') {
            dp[i][0] = 1 + dp[i - 1][0];
        }
        else
            break;
    }
 
    // Iterate through the grid
    for (int i = 1; i < N; i++) {
        for (int j = 1; j < M; j++) {
 
            // If current position
            // is not an obstacle,
            // update the dp state
            if (grid[i][j] == '.') {
                dp[i][j] = min(
                    dp[i][j],
                    1 + min(dp[i - 1][j],
                            dp[i][j - 1]));
            }
        }
    }
 
    // Return answer
    return (dp[N - 1][M - 1] <= K
                ? "Yes"
                : "No");
}
 
// Driver Code
int main()
{
    vector > grid
        = { { '.', '.', '.' },
           { '#', '.', '.' },
           { '#', '#', '.' } };
   
    int K = 4;
    cout << canReach(grid, K);
 
    return 0;
}


Java
// Java implementation for the above approach
//include "bits/stdJava.h"
import java.util.*;
 
class GFG
{
 
// Function to check if it is possible
// to reach the bottom right of the grid
// from top left using atmost K moves
static String canReach(char[][] grid, int K)
{
    int N = grid.length;
    int M = grid[0].length;
 
    // Stores the DP states
    int[][] dp = new int[N][M];
    for(int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++) {
            dp[i][j] = Integer.MAX_VALUE;
        }
    }
   
    // if first cell or last cell is blocked then
    // not possible
    if(grid[0][0] != '.' || grid[N - 1][M - 1] != '.') return "No";
   
    // Initial condition
    dp[0][0] = 0;
 
    // Initializing the DP table
    // in 1st row
    for (int i = 1; i < M; i++) {
        if (grid[0][i] == '.') {
            dp[0][i] = 1 + dp[0][i - 1];
        }
        else
            break;
    }
 
    // Initializing the DP table
    // in 1st column
    for (int i = 1; i < N; i++) {
        if (grid[i][0] == '.') {
            dp[i][0] = 1 + dp[i - 1][0];
        }
        else
            break;
    }
 
    // Iterate through the grid
    for (int i = 1; i < N; i++) {
        for (int j = 1; j < M; j++) {
 
            // If current position
            // is not an obstacle,
            // update the dp state
            if (grid[i][j] == '.') {
                dp[i][j] = Math.min(
                    dp[i][j],
                    1 + Math.min(dp[i - 1][j],
                            dp[i][j - 1]));
            }
        }
    }
 
    // Return answer
    return (dp[N - 1][M - 1] <= K
                ? "Yes"
                : "No");
}
 
// Driver Code
public static void main(String[] args)
{
    char[][] grid
        = { { '.', '.', '.' },
           { '#', '.', '.' },
           { '#', '#', '.' } };
   
    int K = 4;
    System.out.print(canReach(grid, K));
}
}
 
// This code is contributed by 29AjayKumar


Python3
# Python3 implementation for the above approach
INT_MAX = 2147483647
 
# Function to check if it is possible
# to reach the bottom right of the grid
# from top left using atmost K moves
def canReach(grid, K):
     
    N = len(grid)
    M = len(grid[0])
 
    # Stores the DP states
    dp = [[INT_MAX for _ in range(M)]
                   for _ in range(N)]
     
    # if first cell or last cell is blocked then
    # not possible
    if(grid[0][0] != '.' or grid[N - 1][M - 1] != '.'):
      return("No")
   
    # Initial condition
    dp[0][0] = 0
 
    # Initializing the DP table
    # in 1st row
    for i in range(1, M):
        if (grid[0][i] == '.'):
            dp[0][i] = 1 + dp[0][i - 1]
        else:
            break
         
    # Initializing the DP table
    # in 1st column
    for i in range(1, N):
        if (grid[i][0] == '.'):
            dp[i][0] = 1 + dp[i - 1][0]
        else:
            break
 
    # Iterate through the grid
    for i in range(1, N):
        for j in range(1, M):
 
            # If current position
            # is not an obstacle,
            # update the dp state
            if (grid[i][j] == '.'):
                dp[i][j] = min(dp[i][j],
                       1 + min(dp[i - 1][j],
                               dp[i][j - 1]))
 
    # Return answer
    if dp[N - 1][M - 1] <= K:
        return("Yes")
    else:
        return("No")
 
# Driver Code
if __name__ == "__main__":
 
    grid = [ [ '.', '.', '.' ],
             [ '#', '.', '.' ],
             [ '#', '#', '.' ] ]
    K = 4
     
    print(canReach(grid, K))
 
# This code is contributed by rakeshsahni


C#
// C# implementation for the above approach
//include "bits/stdJava.h"
using System;
 
class GFG
{
 
// Function to check if it is possible
// to reach the bottom right of the grid
// from top left using atmost K moves
static String canReach(char[,] grid, int K)
{
    int N = grid.GetLength(0);
    int M = grid.GetLength(1);
 
 
    // Stores the DP states
    int[,] dp = new int[N,M];
    for(int i = 0; i < N; i++)
    {
        for (int j = 0; j < M; j++) {
            dp[i, j] = int.MaxValue;
        }
    }
     
    // if first cell or last cell is blocked then
    // not possible
    if(grid[0, 0] != '.' || grid[N - 1, M - 1] != '.') return "No";
   
    // Initial condition
    dp[0, 0] = 0;
 
    // Initializing the DP table
    // in 1st row
    for (int i = 1; i < M; i++) {
        if (grid[0, i] == '.') {
            dp[0, i] = 1 + dp[0, i - 1];
        }
        else
            break;
    }
 
    // Initializing the DP table
    // in 1st column
    for (int i = 1; i < N; i++) {
        if (grid[i, 0] == '.') {
            dp[i, 0] = 1 + dp[i - 1, 0];
        }
        else
            break;
    }
 
    // Iterate through the grid
    for (int i = 1; i < N; i++) {
        for (int j = 1; j < M; j++) {
 
            // If current position
            // is not an obstacle,
            // update the dp state
            if (grid[i, j] == '.') {
                dp[i, j] = Math.Min(
                    dp[i, j],
                    1 + Math.Min(dp[i - 1, j],
                            dp[i, j - 1]));
            }
        }
    }
 
    // Return answer
    return (dp[N - 1, M - 1] <= K
                ? "Yes"
                : "No");
}
 
// Driver Code
public static void Main()
{
    char[,] grid
        = { { '.', '.', '.' },
            { '/', '.', '.' },
            { '/', '/', '.' } };
    int K = 4;
    Console.Write(canReach(grid, K));
}
}
 
// This code is contributed by Saurabh jaiswal


Javascript


输出
Yes

时间复杂度: O(N * M)
辅助空间: O(N * M)