给定一个大小为M * N的网格mat[][] ,仅由0 s、 1 s 和2 s 组成,其中0代表空地, 1代表一个人, 2代表火,任务是计算最小值需要多少次移动才能使人安全地从网格中出来。在每一步中,火都会燃烧其旁边的细胞,而人将从当前的细胞移动到其旁边的细胞之一。如果无法从网格中出来,则打印-1 。
注意:如果一个人到达网格的边界边之一,则该人将从网格中出来。
例子:
Input: mat[][] = { { 0, 0, 0, 0 }, { 2, 0, 0, 0 }, { 2, 1, 0, 0 }, { 2, 2, 0, 0 } }
Output: 2
Explanation:
Possible moves of the person are (2, 1) → (2, 2) → (2, 3).
The person reaches one of the border sides of the grid(last row) in 2 moves and also it is the minimum possible count.
Therefore, the required output is 2.
Input: mat[][] = { { 0, 2, 0, 0 }, { 2, 1, 0, 2 }, { 2, 0, 0, 0 }, { 2, 0, 2, 0 }}
Output: -1
方法:这个问题可以用解决烂橙子问题的概念来解决。这个想法是对蔓延的火势以及人的动作执行 BFS。请按照以下步骤解决问题:
- 初始化两个空队列fQ和pQ ,分别存储火可以蔓延和人可以移动到的单元格。
- 初始化一个二维数组,比如visited[][] ,以检查单元格(i, j)是否已经被该人访问过。
- 将人的所有边相邻单元入队,并将所有相邻单元标记为访问单元。
- 将火单元的所有边相邻单元入队入fQ,并将所有边相邻单元标记为燃烧单元。
- 初始化一个变量,比如depth ,以跟踪两个单元格之间的最短距离。
- 当pQ不为空时执行以下步骤:
- 将深度增加 1。
- 使pQ 中的所有单元格出列,并将弹出单元格的所有有效边相邻单元入列。
- 如果任何相邻的单元格出现在网格的边界处,则打印深度值。
- 否则,从fQ出列所有单元格。对于每个弹出的单元格,将所有有效的相邻单元格加入队列。
- 从上面的步骤来看,如果不能从网格中出来,则打印-1 。
下面是上述方法的实现:
C++
// C++ program to implement
// the above approach
#include
using namespace std;
// Stores size of the grid
int m, n;
// Function to check valid
// cells of the grid
bool valid(int x, int y)
{
return (x >= 0 && x < m && y >= 0 && y < n);
}
// Checks for the border sides
bool border(int x, int y)
{
return (x == 0 || x == m - 1 || y == 0 || y == n - 1);
}
// Function to find shortest distance
// between two cells of the grid
int minStep(vector> mat)
{
// Rows of the grid
m = mat.size();
// Column of the grid
n = mat[0].size();
// Stores possible move
// of the person
int dx[] = { 1, -1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };
// Store possible cells visited
// by the person
queue > pQ;
// Store possible cells which
// are burning
queue > fQ;
// Traverse the grid
for (int i = 0; i < m; i++){
for (int j = 0; j < n; j++) {
// If current cell is
// burning
if (mat[i][j] == 2)
fQ.push({i, j});
// If person is in
// the current cell
else if (mat[i][j] == 1) {
if (border(i, j))
return 0;
pQ.push({i, j});
}
}
}
// Stores shortest distance
// between two cells
int depth = 0;
// Check if a cell is visited
// by the person or not
vector> visited(n,vector(m,0));
// While pQ is not empty
while (pQ.size()>0) {
// Update depth
depth++;
// Popped all the cells from
// pQ and mark all adjacent cells
// of as visited
for (int i = pQ.size(); i > 0;i--) {
// Front element of
// the queue pQ
pair pos = pQ.front();
// Remove front element of
// the queue pQ
pQ.pop();
// If cuurent cell is burning
if (mat[pos.first][pos.second] == 2)
continue;
// Find all adjacent cells
for (int j = 0; j < 4; j++) {
// Stores row number of
// adjacent cell
int x = pos.first + dx[j];
// Stores column number
// of adjacent cell
int y = pos.second + dy[j];
// Checks if current cell
// is valid
if (valid(x, y) && mat[x][y] != 2 && !visited[x][y]) {
// Mark the cell as visited
visited[x][y] = 1;
// Enqueue the cell
pQ.push(pair (x, y));
// Checks the escape condition
if (border(x, y))
return depth;
}
}
}
// Burn all the adjacent cells
// of burning cells
for (int i = fQ.size(); i > 0; i--) {
// Front element of
// the queue fQ
pair pos = fQ.front();
// Delete front element of
// the queue fQ
fQ.pop();
// Find adjacent cells of
// burning cell
for (int j = 0; j < 4; j++) {
// Stores row number of
// adjacent cell
int x = pos.first + dx[j];
// Stores column number
// of adjacent cell
int y = pos.second + dy[j];
// Checks if current
// cell is valid
if (valid(x, y) && mat[x][y] != 2) {
mat[x][y] = 2;
// Burn all the adjacent
// cells of current cell
fQ.push(pair (x, y));
}
}
}
}
return -1;
}
// Driver Code
int main()
{
// Given grid
vector> grid = { { 0, 0, 0, 0 },
{ 2, 0, 0, 0 },
{ 2, 1, 0, 0 },
{ 2, 2, 0, 0 } };
cout<
Java
// Java program to implement
// the above approach
import java.util.*;
import java.lang.*;
class GFG
{
// Structure of cell
// of the grid
static class pair
{
int x, y;
pair(int x, int y)
{
this.x = x;
this.y = y;
}
}
// Stores size of the grid
static int m, n;
// Function to find shortest distance
// between two cells of the grid
static int minStep(int[][] mat)
{
// Rows of the grid
m = mat.length;
// Column of the grid
n = mat[0].length;
// Stores possible move
// of the person
int dx[] = { 1, -1, 0, 0 };
int dy[] = { 0, 0, 1, -1 };
// Store possible cells visited
// by the person
Queue pQ = new LinkedList<>();
// Store possible cells which
// are burning
Queue fQ = new LinkedList<>();
// Traverse the grid
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
// If current cell is
// burning
if (mat[i][j] == 2)
fQ.add(new pair(i, j));
// If person is in
// the current cell
else if (mat[i][j] == 1)
{
if (border(i, j))
return 0;
pQ.add(new pair(i, j));
}
}
// Stores shortest distance
// between two cells
int depth = 0;
// Check if a cell is visited
// by the person or not
boolean[][] visited
= new boolean[n][m];
// While pQ is not empty
while (!pQ.isEmpty())
{
// Update depth
depth++;
// Popped all the cells from
// pQ and mark all adjacent cells
// of as visited
for (int i = pQ.size(); i > 0; i--)
{
// Front element of
// the queue pQ
pair pos = pQ.peek();
// Remove front element of
// the queue pQ
pQ.remove();
// If cuurent cell is burning
if (mat[pos.x][pos.y] == 2)
continue;
// Find all adjacent cells
for (int j = 0; j < 4; j++)
{
// Stores row number of
// adjacent cell
int x = pos.x + dx[j];
// Stores column number
// of adjacent cell
int y = pos.y + dy[j];
// Checks if current cell
// is valid
if (valid(x, y) && mat[x][y] != 2
&& !visited[x][y])
{
// Mark the cell as visited
visited[x][y] = true;
// Enqueue the cell
pQ.add(new pair(x, y));
// Checks the escape condition
if (border(x, y))
return depth;
}
}
}
// Burn all the adjacent cells
// of burning cells
for (int i = fQ.size(); i > 0; i--)
{
// Front element of
// the queue fQ
pair pos = fQ.peek();
// Delete front element of
// the queue fQ
fQ.remove();
// Find adjacent cells of
// burning cell
for (int j = 0; j < 4; j++)
{
// Stores row number of
// adjacent cell
int x = pos.x + dx[j];
// Stores column number
// of adjacent cell
int y = pos.y + dy[j];
// Checks if current
// cell is valid
if (valid(x, y) && mat[x][y] != 2)
{
mat[x][y] = 2;
// Burn all the adjacent
// cells of current cell
fQ.add(new pair(x, y));
}
}
}
}
return -1;
}
// Function to check valid
// cells of the grid
static boolean valid(int x, int y)
{
return (x >= 0 && x < m
&& y >= 0 && y < n);
}
// Checks for the border sides
static boolean border(int x, int y)
{
return (x == 0 || x == m - 1
|| y == 0 || y == n - 1);
}
// Driver Code
public static void main(String[] args)
{
// Given grid
int[][] grid = { { 0, 0, 0, 0 },
{ 2, 0, 0, 0 },
{ 2, 1, 0, 0 },
{ 2, 2, 0, 0 } };
System.out.println(minStep(grid));
}
}
// This code is contributed by mohit kumar 29.
Python3
# Python3 program to implement
# the above approach
# Stores size of the grid
m = 0
n = 0
# Function to check valid
# cells of the grid
def valid(x, y):
global n
global m
return (x >= 0 and x < m and
y >= 0 and y < n)
# Checks for the border sides
def border(x, y):
global n
global m
return (x == 0 or x == m - 1 or
y == 0 or y == n - 1)
# Function to find shortest distance
# between two cells of the grid
def minStep(mat):
global n
global m
# Rows of the grid
m = len(mat)
# Column of the grid
n = len(mat[0])
# Stores possible move
# of the person
dx = [1, -1, 0, 0]
dy = [0, 0, 1, -1]
# Store possible cells visited
# by the person
pQ = []
# Store possible cells which
# are burning
fQ = []
# Traverse the grid
for i in range(m):
for j in range(n):
# If current cell is
# burning
if (mat[i][j] == 2):
fQ.append([i, j])
# If person is in
# the current cell
elif(mat[i][j] == 1):
if (border(i, j)):
return 0
pQ.append([i, j])
# Stores shortest distance
# between two cells
depth = 0
# Check if a cell is visited
# by the person or not
visited = [[0 for i in range(m)]
for j in range(n)]
# While pQ is not empty
while (len(pQ) > 0):
# Update depth
depth += 1
# Popped all the cells from
# pQ and mark all adjacent cells
# of as visited
i = len(pQ)
while(i > 0):
# Front element of
# the queue pQ
pos = pQ[0]
# Remove front element of
# the queue pQ
pQ.remove(pQ[0])
# If cuurent cell is burning
if (mat[pos[0]][pos[1]] == 2):
continue
# Find all adjacent cells
for j in range(4):
# Stores row number of
# adjacent cell
x = pos[0] + dx[j]
# Stores column number
# of adjacent cell
y = pos[1] + dy[j]
# Checks if current cell
# is valid
if (valid(x, y) and mat[x][y] != 2 and
visited[x][y] == 0):
# Mark the cell as visited
visited[x][y] = 1
# Enqueue the cell
pQ.append([x, y])
# Checks the escape condition
if (border(x, y)):
return depth
i -= 1
# Burn all the adjacent cells
# of burning cells
i = len(fQ)
while(i > 0):
# Front element of
# the queue fQ
pos = fQ[0]
# Delete front element of
# the queue fQ
fQ.remove(fQ[0])
# Find adjacent cells of
# burning cell
for j in range(4):
# Stores row number of
# adjacent cell
x = pos[0] + dx[j]
# Stores column number
# of adjacent cell
y = pos[1] + dy[j]
# Checks if current
# cell is valid
if (valid(x, y) and mat[x][y] != 2):
mat[x][y] = 2
# Burn all the adjacent
# cells of current cell
fQ.append([x, y])
i -= 1
return -1
# Driver Code
if __name__ == '__main__':
# Given grid
grid = [ [ 0, 0, 0, 0 ],
[ 2, 0, 0, 0 ],
[ 2, 1, 0, 0 ],
[ 2, 2, 0, 0 ] ]
print(minStep(grid))
# This code is contributed by SURENDRA_GANGWAR
C#
// C# program to implement
// the above approach
using System;
using System.Collections.Generic;
public class GFG
{
// Structure of cell
// of the grid
class pair
{
public int x, y;
public pair(int x, int y)
{
this.x = x;
this.y = y;
}
}
// Stores size of the grid
static int m, n;
// Function to find shortest distance
// between two cells of the grid
static int minStep(int[,] mat)
{
// Rows of the grid
m = mat.GetLength(0);
// Column of the grid
n = mat.GetLength(1);
// Stores possible move
// of the person
int []dx = { 1, -1, 0, 0 };
int []dy = { 0, 0, 1, -1 };
// Store possible cells visited
// by the person
Queue pQ = new Queue();
// Store possible cells which
// are burning
Queue fQ = new Queue();
// Traverse the grid
for (int i = 0; i < m; i++)
for (int j = 0; j < n; j++)
{
// If current cell is
// burning
if (mat[i, j] == 2)
fQ.Enqueue(new pair(i, j));
// If person is in
// the current cell
else if (mat[i, j] == 1)
{
if (border(i, j))
return 0;
pQ.Enqueue(new pair(i, j));
}
}
// Stores shortest distance
// between two cells
int depth = 0;
// Check if a cell is visited
// by the person or not
bool[,] visited
= new bool[n, m];
// While pQ is not empty
while (pQ.Count != 0)
{
// Update depth
depth++;
// Popped all the cells from
// pQ and mark all adjacent cells
// of as visited
for (int i = pQ.Count; i > 0; i--)
{
// Front element of
// the queue pQ
pair pos = pQ.Peek();
// Remove front element of
// the queue pQ
pQ.Dequeue();
// If cuurent cell is burning
if (mat[pos.x, pos.y] == 2)
continue;
// Find all adjacent cells
for (int j = 0; j < 4; j++)
{
// Stores row number of
// adjacent cell
int x = pos.x + dx[j];
// Stores column number
// of adjacent cell
int y = pos.y + dy[j];
// Checks if current cell
// is valid
if (valid(x, y) && mat[x, y] != 2
&& !visited[x, y])
{
// Mark the cell as visited
visited[x, y] = true;
// Enqueue the cell
pQ.Enqueue(new pair(x, y));
// Checks the escape condition
if (border(x, y))
return depth;
}
}
}
// Burn all the adjacent cells
// of burning cells
for (int i = fQ.Count; i > 0; i--)
{
// Front element of
// the queue fQ
pair pos = fQ.Peek();
// Delete front element of
// the queue fQ
fQ.Dequeue();
// Find adjacent cells of
// burning cell
for (int j = 0; j < 4; j++)
{
// Stores row number of
// adjacent cell
int x = pos.x + dx[j];
// Stores column number
// of adjacent cell
int y = pos.y + dy[j];
// Checks if current
// cell is valid
if (valid(x, y) && mat[x, y] != 2)
{
mat[x, y] = 2;
// Burn all the adjacent
// cells of current cell
fQ.Enqueue(new pair(x, y));
}
}
}
}
return -1;
}
// Function to check valid
// cells of the grid
static bool valid(int x, int y)
{
return (x >= 0 && x < m
&& y >= 0 && y < n);
}
// Checks for the border sides
static bool border(int x, int y)
{
return (x == 0 || x == m - 1
|| y == 0 || y == n - 1);
}
// Driver Code
public static void Main(String[] args)
{
// Given grid
int[,] grid = { { 0, 0, 0, 0 },
{ 2, 0, 0, 0 },
{ 2, 1, 0, 0 },
{ 2, 2, 0, 0 } };
Console.WriteLine(minStep(grid));
}
}
// This code is contributed by shikhasingrajput
Javascript
2
时间复杂度: O(N * M)
辅助空间: O(N * M)
如果您想与行业专家一起参加直播课程,请参阅Geeks Classes Live