给定2D数组(mxn)。任务是检查从左上角到右下角是否有任何路径。在矩阵中,-1被视为阻塞(无法通过此单元格),0被视为路径单元(可以通过此单元格)。
注意:左上方的单元格始终包含0
例子:
Input : arr[][] = {{ 0, 0, 0, -1, 0},
{-1, 0, 0, -1, -1},
{ 0, 0, 0, -1, 0},
{-1, 0, 0, 0, 0},
{ 0, 0, -1, 0, 0}}
Output : Yes
Explanation:
The red cells are blocked, white cell denotes the path and the green cells are not blocked cells.
Input : arr[][] = {{ 0, 0, 0, -1, 0},
{-1, 0, 0, -1, -1},
{ 0, 0, 0, -1, 0},
{-1, 0, -1, 0, 0},
{ 0, 0, -1, 0, 0}}
Output : No
Explanation: There exists no path from start to end.
The red cells are blocked, white cell denotes the path and the green cells are not blocked cells.
方法1
- 方法:解决方案是执行BFS或DFS以查找是否存在路径。无需创建图形即可执行bfs,但矩阵本身将用作图形。从右上角开始遍历,如果有到达右下角的方法,则有一条路径。
- 算法:
- 创建一个存储对(i,j)的队列,并将(0,0)插入该队列中。
- 循环运行直到队列为空。
- 在每次迭代中使队列(a,b)出队,如果最前面的元素是目的地(row-1,col-1),则返回1,即存在一条路径并更改mat [a] [b ]到-1,即已访问。
- 否则在矩阵[i] [j]的值不为-1的情况下插入相邻的索引。
- 执行:
C++
// C++ program to find if there is path
// from top left to right bottom
#include
using namespace std;
#define row 5
#define col 5
// to find the path from
// top left to bottom right
bool isPath(int arr[row][col])
{
//directions
int dir[4][2] = { {0,1}, {0,-1}, {1,0}, {-1,0}};
//queue
queue > q;
//insert the top right corner.
q.push(make_pair(0,0));
//until queue is empty
while(q.size()>0)
{
pair p = q.front();
q.pop();
//mark as visited
arr[p.first][p.second] = -1;
//destination is reached.
if(p == make_pair(row-1,col-1))
return true;
//check all four directions
for(int i=0; i<4 ;i++)
{
//using the direction array
int a = p.first + dir[i][0];
int b = p.second + dir[i][1];
//not blocked and valid
if(arr[a][b]!=-1&& a>=0 && b>=0
&& a|
Python3
# Python3 program to find if there is path
# from top left to right bottom
row = 5
col = 5
# to find the path from
# top left to bottom right
def isPath(arr) :
# directions
Dir = [ [0, 1], [0, -1], [1, 0], [-1, 0]]
# queue
q = []
# insert the top right corner.
q.append((0, 0))
# until queue is empty
while(len(q) > 0) :
p = q[0]
q.pop(0)
# mark as visited
arr[p[0]][p[1]] = -1
# destination is reached.
if(p == (row - 1, col - 1)) :
return True
# check all four directions
for i in range(4) :
# using the direction array
a = p[0] + Dir[i][0]
b = p[1] + Dir[i][1]
# not blocked and valid
if(a >= 0 and b >= 0 and a < row and b < col and arr[a][b] != -1) :
q.append((a, b))
return False
# Given array
arr = [ [ 0, 0, 0, -1, 0 ],
[ -1, 0, 0, -1, -1 ],
[ 0, 0, 0, -1, 0 ],
[ -1, 0, -1, 0, -1 ],
[ 0, 0, -1, 0, 0 ] ]
# path from arr[0][0] to arr[row][col]
if (isPath(arr)) :
print("Yes")
else :
print("No")
# This code is contributed by divyesh072019
C#
// C# program to find if there is path
// from top left to right bottom
using System;
using System.Collections;
class GFG{
static int row = 5;
static int col = 5;
// To find the path from
// top left to bottom right
static bool isPath(int[,] arr)
{
// Directions
int[,] dir = { { 0, 1 }, { 0, -1 },
{ 1, 0 }, { -1, 0 } };
// Queue
Queue q = new Queue();
// Insert the top right corner.
q.Enqueue(new Tuple(0, 0));
// Until queue is empty
while (q.Count > 0)
{
Tuple p = (Tuple)(q.Peek());
q.Dequeue();
// Mark as visited
arr[p.Item1, p.Item2] = -1;
// Destination is reached.
if (p == new Tuple(row - 1, col - 1))
return true;
// Check all four directions
for(int i = 0; i < 4; i++)
{
// Using the direction array
int a = p.Item1 + dir[i, 0];
int b = p.Item2 + dir[i, 1];
// Not blocked and valid
if (a >= 0 && b >= 0 &&
a < row && b < col &&
arr[a, b] != -1)
{
q.Enqueue(new Tuple(a, b));
}
}
}
return false;
}
// Driver Code
static void Main()
{
// Given array
int[,] arr = { { 0, 0, 0, -1, 0 },
{ -1, 0, 0, -1, -1 },
{ 0, 0, 0, -1, 0 },
{ -1, 0, -1, 0, -1 },
{ 0, 0, -1, 0, 0 } };
// Path from arr[0][0] to arr[row][col]
if (isPath(arr))
Console.Write("Yes");
else
Console.Write("No");
}
}
// This code is contributed by divyeshrabadiya07
C++
// C++ program to find if there is path
// from top left to right bottom
#include
using namespace std;
#define row 5
#define col 5
// to find the path from
// top left to bottom right
bool isPath(int arr[row][col])
{
// set arr[0][0] = 1
arr[0][0] = 1;
// Mark reachable (from top left) nodes
// in first row and first column.
for (int i = 1; i < row; i++)
if (arr[i][0] != -1)
arr[i][0] = arr[i - 1][0];
for (int j = 1; j < col; j++)
if (arr[0][j] != -1)
arr[0][j] = arr[0][j - 1];
// Mark reachable nodes in remaining
// matrix.
for (int i = 1; i < row; i++)
for (int j = 1; j < col; j++)
if (arr[i][j] != -1)
arr[i][j] = max(arr[i][j - 1],
arr[i - 1][j]);
// return yes if right bottom
// index is 1
return (arr[row - 1][col - 1] == 1);
}
// Driver Code
int main()
{
// Given array
int arr[row][col] = { { 0, 0, 0, -1, 0 },
{ -1, 0, 0, -1, -1 },
{ 0, 0, 0, -1, 0 },
{ -1, 0, -1, 0, -1 },
{ 0, 0, -1, 0, 0 } };
// path from arr[0][0] to arr[row][col]
if (isPath(arr))
cout << "Yes";
else
cout << "No";
return 0;
}
Java
// Java program to find if there is path
// from top left to right bottom
class GFG
{
// to find the path from
// top left to bottom right
static boolean isPath(int arr[][])
{
// set arr[0][0] = 1
arr[0][0] = 1;
// Mark reachable (from top left) nodes
// in first row and first column.
for (int i = 1; i < 5; i++)
if (arr[0][i] != -1)
arr[0][i] = arr[0][i - 1];
for (int j = 1; j < 5; j++)
if (arr[j][0] != -1)
arr[j][0] = arr[j - 1][0];
// Mark reachable nodes in
// remaining matrix.
for (int i = 1; i < 5; i++)
for (int j = 1; j < 5; j++)
if (arr[i][j] != -1)
arr[i][j] = Math.max(arr[i][j - 1],
arr[i - 1][j]);
// return yes if right
// bottom index is 1
return (arr[5 - 1][5 - 1] == 1);
}
//Driver code
public static void main(String[] args)
{
// Given array
int arr[][] = { { 0, 0, 0, -1, 0 },
{ -1, 0, 0, -1, -1 },
{ 0, 0, 0, -1, 0 },
{ -1, 0, -1, 0, -1 },
{ 0, 0, -1, 0, 0 } };
// path from arr[0][0]
// to arr[row][col]
if (isPath(arr))
System.out.println("Yes");
else
System.out.println("No");
}
}
// This code is contributed
// by prerna saini
Python3
# Python3 program to find if there
# is path from top left to right bottom
row = 5
col = 5
# to find the path from
# top left to bottom right
def isPath(arr):
# set arr[0][0] = 1
arr[0][0] = 1
# Mark reachable (from top left)
# nodes in first row and first column.
for i in range(1, row):
if (arr[i][0] != -1):
arr[i][0] = arr[i-1][0]
for j in range(1, col):
if (arr[0][j] != -1):
arr[0][j] = arr[0][j-1]
# Mark reachable nodes in
# remaining matrix.
for i in range(1, row):
for j in range(1, col):
if (arr[i][j] != -1):
arr[i][j] = max(arr[i][j - 1],
arr[i - 1][j])
# return yes if right
# bottom index is 1
return (arr[row - 1][col - 1] == 1)
# Driver Code
# Given array
arr = [[ 0, 0, 0, -1, 0 ],
[-1, 0, 0, -1, -1],
[ 0, 0, 0, -1, 0 ],
[-1, 0, -1, 0, -1],
[ 0, 0, -1, 0, 0 ]]
# path from arr[0][0] to arr[row][col]
if (isPath(arr)):
print("Yes")
else:
print("No")
# This code is contributed
# by sahilshelangia
C#
// C# program to find if there is path
// from top left to right bottom
using System;
class GFG
{
// to find the path from
// top left to bottom right
static bool isPath(int [,]arr)
{
// set arr[0][0] = 1
arr[0, 0] = 1;
// Mark reachable (from top left) nodes
// in first row and first column.
for (int i = 1; i < 5; i++)
if (arr[i, 0] != -1)
arr[i, 0] = arr[i - 1, 0];
for (int j = 1; j < 5; j++)
if (arr[0,j] != -1)
arr[0,j] = arr[0, j - 1];
// Mark reachable nodes in
// remaining matrix.
for (int i = 1; i < 5; i++)
for (int j = 1; j < 5; j++)
if (arr[i, j] != -1)
arr[i, j] = Math.Max(arr[i, j - 1],
arr[i - 1, j]);
// return yes if right
// bottom index is 1
return (arr[5 - 1, 5 - 1] == 1);
}
//Driver code
public static void Main()
{
// Given array
int [,]arr = { { 0, 0, 0, -1, 0 },
{ -1, 0, 0, -1, -1 },
{ 0, 0, 0, -1, 0 },
{ -1, 0, -1, 0, -1 },
{ 0, 0, -1, 0, 0 } };
// path from arr[0][0]
// to arr[row][col]
if (isPath(arr))
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
}
// This code is contributed
// by vt_m
PHP
Javascript
输出:
No
- 复杂度分析:
- 时间复杂度: O(R * C)。
矩阵的每个元素都可以在队列中插入一次,因此时间复杂度为O(R * C)。 - 空间复杂度: O(R * C)。
要将所有元素存储在队列中,需要O(R * C)空间。
- 时间复杂度: O(R * C)。
方法二
- 方法:上述解决方案的唯一问题是它占用了额外的空间。这种方法将消除对额外空间的需求。基本思想非常相似。该算法也将执行BFS,但是通过标记阵列可以消除对额外空间的需求。因此,首先运行一个循环,并仅使用第一行和第一列,检查从0,0可访问第一列和第一行的哪些元素。将它们标记为1。现在以递增的行和列索引从行到行遍历矩阵。如果该信元未被阻塞,则检查其相邻信元中的任何一个是否标记为1。如果标记为1,则标记单元格1。
- 算法:
- 将单元格0,0标记为1。
- 运行从0到行长的循环,如果上面的单元格标记为1并且当前单元格未被阻塞,则将当前单元格标记为1。
- 运行从0到列长的循环,如果左侧单元格标记为1并且当前单元格未被阻塞,则将当前单元格标记为1。
- 按行和列的递增索引从开始到结束逐行遍历矩阵。
- 如果该单元格未被阻塞,则检查其相邻的单元格中的任何一个(仅检查上方的单元格和左侧的单元格)。是否标记为1。如果标记为1,则标记单元格1。
- 如果单元格(行1,列1)标记为1,则返回true,否则返回false。
- 执行:
C++
// C++ program to find if there is path
// from top left to right bottom
#include
using namespace std;
#define row 5
#define col 5
// to find the path from
// top left to bottom right
bool isPath(int arr[row][col])
{
// set arr[0][0] = 1
arr[0][0] = 1;
// Mark reachable (from top left) nodes
// in first row and first column.
for (int i = 1; i < row; i++)
if (arr[i][0] != -1)
arr[i][0] = arr[i - 1][0];
for (int j = 1; j < col; j++)
if (arr[0][j] != -1)
arr[0][j] = arr[0][j - 1];
// Mark reachable nodes in remaining
// matrix.
for (int i = 1; i < row; i++)
for (int j = 1; j < col; j++)
if (arr[i][j] != -1)
arr[i][j] = max(arr[i][j - 1],
arr[i - 1][j]);
// return yes if right bottom
// index is 1
return (arr[row - 1][col - 1] == 1);
}
// Driver Code
int main()
{
// Given array
int arr[row][col] = { { 0, 0, 0, -1, 0 },
{ -1, 0, 0, -1, -1 },
{ 0, 0, 0, -1, 0 },
{ -1, 0, -1, 0, -1 },
{ 0, 0, -1, 0, 0 } };
// path from arr[0][0] to arr[row][col]
if (isPath(arr))
cout << "Yes";
else
cout << "No";
return 0;
}
Java
// Java program to find if there is path
// from top left to right bottom
class GFG
{
// to find the path from
// top left to bottom right
static boolean isPath(int arr[][])
{
// set arr[0][0] = 1
arr[0][0] = 1;
// Mark reachable (from top left) nodes
// in first row and first column.
for (int i = 1; i < 5; i++)
if (arr[0][i] != -1)
arr[0][i] = arr[0][i - 1];
for (int j = 1; j < 5; j++)
if (arr[j][0] != -1)
arr[j][0] = arr[j - 1][0];
// Mark reachable nodes in
// remaining matrix.
for (int i = 1; i < 5; i++)
for (int j = 1; j < 5; j++)
if (arr[i][j] != -1)
arr[i][j] = Math.max(arr[i][j - 1],
arr[i - 1][j]);
// return yes if right
// bottom index is 1
return (arr[5 - 1][5 - 1] == 1);
}
//Driver code
public static void main(String[] args)
{
// Given array
int arr[][] = { { 0, 0, 0, -1, 0 },
{ -1, 0, 0, -1, -1 },
{ 0, 0, 0, -1, 0 },
{ -1, 0, -1, 0, -1 },
{ 0, 0, -1, 0, 0 } };
// path from arr[0][0]
// to arr[row][col]
if (isPath(arr))
System.out.println("Yes");
else
System.out.println("No");
}
}
// This code is contributed
// by prerna saini
Python3
# Python3 program to find if there
# is path from top left to right bottom
row = 5
col = 5
# to find the path from
# top left to bottom right
def isPath(arr):
# set arr[0][0] = 1
arr[0][0] = 1
# Mark reachable (from top left)
# nodes in first row and first column.
for i in range(1, row):
if (arr[i][0] != -1):
arr[i][0] = arr[i-1][0]
for j in range(1, col):
if (arr[0][j] != -1):
arr[0][j] = arr[0][j-1]
# Mark reachable nodes in
# remaining matrix.
for i in range(1, row):
for j in range(1, col):
if (arr[i][j] != -1):
arr[i][j] = max(arr[i][j - 1],
arr[i - 1][j])
# return yes if right
# bottom index is 1
return (arr[row - 1][col - 1] == 1)
# Driver Code
# Given array
arr = [[ 0, 0, 0, -1, 0 ],
[-1, 0, 0, -1, -1],
[ 0, 0, 0, -1, 0 ],
[-1, 0, -1, 0, -1],
[ 0, 0, -1, 0, 0 ]]
# path from arr[0][0] to arr[row][col]
if (isPath(arr)):
print("Yes")
else:
print("No")
# This code is contributed
# by sahilshelangia
C#
// C# program to find if there is path
// from top left to right bottom
using System;
class GFG
{
// to find the path from
// top left to bottom right
static bool isPath(int [,]arr)
{
// set arr[0][0] = 1
arr[0, 0] = 1;
// Mark reachable (from top left) nodes
// in first row and first column.
for (int i = 1; i < 5; i++)
if (arr[i, 0] != -1)
arr[i, 0] = arr[i - 1, 0];
for (int j = 1; j < 5; j++)
if (arr[0,j] != -1)
arr[0,j] = arr[0, j - 1];
// Mark reachable nodes in
// remaining matrix.
for (int i = 1; i < 5; i++)
for (int j = 1; j < 5; j++)
if (arr[i, j] != -1)
arr[i, j] = Math.Max(arr[i, j - 1],
arr[i - 1, j]);
// return yes if right
// bottom index is 1
return (arr[5 - 1, 5 - 1] == 1);
}
//Driver code
public static void Main()
{
// Given array
int [,]arr = { { 0, 0, 0, -1, 0 },
{ -1, 0, 0, -1, -1 },
{ 0, 0, 0, -1, 0 },
{ -1, 0, -1, 0, -1 },
{ 0, 0, -1, 0, 0 } };
// path from arr[0][0]
// to arr[row][col]
if (isPath(arr))
Console.WriteLine("Yes");
else
Console.WriteLine("No");
}
}
// This code is contributed
// by vt_m
的PHP
Java脚本
输出:
No
- 复杂度分析:
- 时间复杂度: O(R * C)。
遍历矩阵的每个元素,因此时间复杂度为O(R * C)。 - 空间复杂度: O(1)。
不需要额外的空间。
- 时间复杂度: O(R * C)。