检查给定矩阵中是否存在从开始到结束单元格的路径,障碍物最多 K 次移动
给定一个正整数K和一个由字符'.'组成的维度为N * M的矩阵网格。和'#' ,其中'.'表示未阻塞的单元格, '#'表示阻塞的单元格,任务是检查是否可以通过最多K次移动的未阻塞单元格从矩阵的左上角单元格到达网格的右下角,使得向右或向下移动到其相邻的单元格需要移动一次。
例子:
Input: grid[][] = {{‘.’, ‘.’, ‘.’}, {‘#’, ‘.’, ‘.’}, {‘#’, ‘#’, ‘.’}}, K = 4
Output: Yes
Explanation: It is possible to reach the bottom right cell of the given grid using the following set of moves: right-> down -> right -> down. Hence, the number of moves required are 4 which is the minimum possible and is less than K.
Input: grid[][] = {{‘.’, ‘.’, ‘.’, ‘.’}, {‘.’, ‘.’, ‘.’, ‘.’}, {‘#’, ‘#’, ‘#’, ‘#’}, {‘.’, ‘.’, ‘.’, ‘.’}}, K = 4
Output: No
Explanation: There are no possible set of moves to reach the bottom right cell from the top left cell of the given matrix.
方法:给定的问题可以在动态规划的帮助下使用制表方法来解决。它可以通过使用类似于本文中讨论的方法预先计算从左上角移动到右下角单元格所需的最小移动次数来解决。可以看出,如果dp[i][j]表示从(0, 0)到达单元格(i, j)的最小移动次数,则 DP 关系可以表述为:
dp[i][j] = min(dp[i][j], 1 + dp[i – 1][j], 1+ dp[i][j – 1]))
此后,如果最小移动次数最多为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)