给定一个二维数组(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.
方法一
- 处理方法:解决方法是进行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|
Java
// Java program to find if there is path
// from top left to right bottom
import java.io.*;
import java.util.*;
class pair
{
int Item1, Item2;
pair(int f, int s)
{
Item1 = f;
Item2 = s;
}
}
class GFG{
static int row = 5;
static int col = 5;
// To find the path from
// top left to bottom right
static boolean isPath(int[][] arr)
{
// Directions
int[][] dir = { { 0, 1 }, { 0, -1 },
{ 1, 0 }, { -1, 0 } };
// Queue
Queue q = new LinkedList<>();
// Insert the top right corner.
q.add(new pair(0, 0));
// Until queue is empty
while (q.size() > 0)
{
pair p = (q.peek());
q.remove();
// Mark as visited
arr[p.Item1][ p.Item2] = -1;
// Destination is reached.
if (p == new 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.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.add(new pair(a, b));
}
}
}
return false;
}
// 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 avanitrachhadiya2155
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
Javascript
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。
- 如果单元格 (row-1, col-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
蟒蛇3
# 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(1)。
不需要额外的空间。
- 时间复杂度: O(R*C)。
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。