给定一个维度为N * M的二进制矩阵mat[][]以及分别代表源和目标单元格的整数对src和dest ,任务是通过单元格找到从给定源单元格到目标单元格的最短移动序列仅由1秒组成。允许的移动是向左( L )、向右( R )、向上( U ) 和向下( D ) 移动单元格(如果存在)。如果不存在这样的路径,则打印“-1” 。否则,打印移动序列。
例子:
Input: mat[][] = {{‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’}, {‘0’, ‘1’, ‘1’, ‘1’, ‘1’, ‘0’}, {‘0’, ‘1’, ‘0’, ‘1’, ‘1’, ‘1’}, {‘0’, ‘1’, ‘1’, ‘1’, ‘1’, ‘0’}, {‘0’, ‘0’, ‘0’, ‘0’, ‘0’, ‘0’}}, src = {1, 2}, dest = {2, 4}
Output: LDDRRRU
Explanation:
Following sequence of moves starting from the source cell (1, 2) to the destination cell (2, 4) is the shortest path possible:
(1, 2) -> (1, 1) -> (2, 1) -> (3, 1) -> (3, 2) -> (3, 3) -> (3, 4) -> (2, 4)
start -> Left -> Down -> Down ->Right -> Right -> Right -> Up
Therefore, the resultant path is LDDRRRRU.
Input: mat[][] = {{‘0’, ‘1’, ‘0’, ‘1’}, {‘1’, ‘0’, ‘1’, ‘1’}, {‘1’, ‘1’, ‘1’, ‘1’}, {‘1’, ‘0’, ‘0’, ‘0’}}, src = {0, 3}, dest = {3, 0}
Output: DDLLLD
方法:可以通过对给定矩阵从给定源单元格到目标单元格执行 BFS 遍历来解决给定问题。
请按照以下步骤解决给定的问题:
- 初始化在给定矩阵上执行 BFS 遍历所需的队列。
- 初始化一个布尔矩阵,比如visited[N][M] ,用于检查给定的单元格是否被访问过。最初,将所有索引设置为false 。
- 初始化另一个矩阵,例如distance[N][M] ,用于存储从源节点到每个单元格的最短距离。将其初始化为-1 。
- 将字符串pathMoves初始化为“”以存储从源到目标单元格的路径。
- 将源节点推入队列,距离为0 。
- 迭代直到队列不为空并执行以下步骤:
- 弹出队列的前端节点,比如currentNode 。
- 检查弹出的节点是否是目标节点。如果发现为真,则使用回溯找到从目标单元格到源单元格的路径。
- 否则,插入当前弹出节点的所有未访问的相邻单元格,距离为(previous distance + 1) 。将distance[currentNode.x][currentNode.y]的值更新为(currentDistance + 1) 。
- 完成上述步骤后,如果从给定源到目标单元格的路径存在,则打印存储在pathMoves 中的路径作为结果。否则,打印“-1” 。
下面是上述方法的实现:
C++
// C++ program for the above approach
#include
using namespace std;
#define ROW 4
#define COL 4
// Stores the coordinates
// of the matrix cell
struct Point {
int x, y;
};
// Stores coordinates of
// a cell and its distance
struct Node {
Point pt;
int dist;
};
// Check if the given cell is valid or not
bool isValid(int row, int col)
{
return (row >= 0) && (col >= 0)
&& (row < ROW) && (col < COL);
}
// Stores the moves of the directions of adjacent cells
int dRow[] = { -1, 0, 0, 1 };
int dCol[] = { 0, -1, 1, 0 };
// Function to find the shortest path from the
// source to destination in the given matrix
void pathMoves(char mat[][COL],
Point src, Point dest)
{
// Stores the distance for each
// cell from the source cell
int d[ROW][COL];
memset(d, -1, sizeof d);
// Distance of source cell is 0
d[src.x][src.y] = 0;
// Initialize a visited array
bool visited[ROW][COL];
memset(visited, false, sizeof visited);
// Mark source cell as visited
visited[src.x][src.y] = true;
// Create a queue for BFS
queue q;
// Distance of source cell is 0
Node s = { src, 0 };
// Enqueue source cell
q.push(s);
// Keeps track of whether
// destination is reached or not
bool ok = false;
// Iterate until queue is not empty
while (!q.empty()) {
// Deque front of the queue
Node curr = q.front();
Point pt = curr.pt;
// If the destination cell is
// reached, then find the path
if (pt.x == dest.x
&& pt.y == dest.y) {
int xx = pt.x, yy = pt.y;
int dist = curr.dist;
// Assign the distance of
// destination to the
// distance matrix
d[pt.x][pt.y] = dist;
// Stores the smallest path
string pathmoves = "";
// Iterate until source is reached
while (xx != src.x
|| yy != src.y) {
// Append D
if (xx > 0 && d[xx - 1][yy] == dist - 1) {
pathmoves += 'D';
xx--;
}
// Append U
if (xx < ROW - 1
&& d[xx + 1][yy]
== dist - 1) {
pathmoves += 'U';
xx++;
}
// Append R
if (yy > 0 && d[xx][yy - 1] == dist - 1) {
pathmoves += 'R';
yy--;
}
// Append L
if (yy < COL - 1
&& d[xx][yy + 1]
== dist - 1) {
pathmoves += 'L';
yy++;
}
dist--;
}
// Reverse the backtracked path
reverse(pathmoves.begin(),
pathmoves.end());
cout << pathmoves;
ok = true;
break;
}
// Pop the start of queue
q.pop();
// Explore all adjacent directions
for (int i = 0; i < 4; i++) {
int row = pt.x + dRow[i];
int col = pt.y + dCol[i];
// If the current cell is valid
// cell and can be traversed
if (isValid(row, col)
&& (mat[row][col] == '1'
|| mat[row][col] == 's'
|| mat[row][col] == 'd')
&& !visited[row][col]) {
// Mark the adjacent cells as visited
visited[row][col] = true;
// Enque the adjacent cells
Node adjCell
= { { row, col }, curr.dist + 1 };
q.push(adjCell);
// Update the distance
// of the adjacent cells
d[row][col] = curr.dist + 1;
}
}
}
// If the destination
// is not reachable
if (!ok)
cout << -1;
}
// Driver Code
int main()
{
char mat[ROW][COL] = { { '0', '1', '0', '1' },
{ '1', '0', '1', '1' },
{ '0', '1', '1', '1' },
{ '1', '1', '1', '0' } };
Point src = { 0, 3 };
Point dest = { 3, 0 };
pathMoves(mat, src, dest);
return 0;
}
Java
// Java program for the above approach
import java.io.*;
import java.lang.*;
import java.util.*;
class GFG{
static int ROW;
static int COL;
// Stores the coordinates
// of the matrix cell
static class Point
{
int x, y;
Point(int x, int y)
{
this.x = x;
this.y = y;
}
}
// Stores coordinates of
// a cell and its distance
static class Node
{
Point pt;
int dist;
Node(Point p, int dist)
{
this.pt = p;
this.dist = dist;
}
}
// Check if the given cell is valid or not
static boolean isValid(int row, int col)
{
return (row >= 0) && (col >= 0) &&
(row < ROW) && (col < COL);
}
// Stores the moves of the directions
// of adjacent cells
static int dRow[] = { -1, 0, 0, 1 };
static int dCol[] = { 0, -1, 1, 0 };
// Function to find the shortest path from the
// source to destination in the given matrix
static void pathMoves(char mat[][], Point src,
Point dest)
{
// Stores the distance for each
// cell from the source cell
int d[][] = new int[ROW][COL];
for(int dd[] : d)
Arrays.fill(dd, -1);
// Distance of source cell is 0
d[src.x][src.y] = 0;
// Initialize a visited array
boolean visited[][] = new boolean[ROW][COL];
// Mark source cell as visited
visited[src.x][src.y] = true;
// Create a queue for BFS
ArrayDeque q = new ArrayDeque<>();
// Distance of source cell is 0
Node s = new Node(src, 0);
// Enqueue source cell
q.addLast(s);
// Keeps track of whether
// destination is reached or not
boolean ok = false;
// Iterate until queue is not empty
while (!q.isEmpty())
{
// Deque front of the queue
Node curr = q.removeFirst();
Point pt = curr.pt;
// If the destination cell is
// reached, then find the path
if (pt.x == dest.x && pt.y == dest.y)
{
int xx = pt.x, yy = pt.y;
int dist = curr.dist;
// Assign the distance of
// destination to the
// distance matrix
d[pt.x][pt.y] = dist;
// Stores the smallest path
String pathmoves = "";
// Iterate until source is reached
while (xx != src.x || yy != src.y)
{
// Append D
if (xx > 0 &&
d[xx - 1][yy] == dist - 1)
{
pathmoves += 'D';
xx--;
}
// Append U
if (xx < ROW - 1 &&
d[xx + 1][yy] == dist - 1)
{
pathmoves += 'U';
xx++;
}
// Append R
if (yy > 0 &&
d[xx][yy - 1] == dist - 1)
{
pathmoves += 'R';
yy--;
}
// Append L
if (yy < COL - 1 &&
d[xx][yy + 1] == dist - 1)
{
pathmoves += 'L';
yy++;
}
dist--;
}
// Print reverse the backtracked path
for(int i = pathmoves.length() - 1;
i >= 0; --i)
System.out.print(pathmoves.charAt(i));
ok = true;
break;
}
// Pop the start of queue
if (!q.isEmpty())
q.removeFirst();
// Explore all adjacent directions
for(int i = 0; i < 4; i++)
{
int row = pt.x + dRow[i];
int col = pt.y + dCol[i];
// If the current cell is valid
// cell and can be traversed
if (isValid(row, col) &&
(mat[row][col] == '1' ||
mat[row][col] == 's' ||
mat[row][col] == 'd') &&
!visited[row][col])
{
// Mark the adjacent cells as visited
visited[row][col] = true;
// Enque the adjacent cells
Node adjCell = new Node(
new Point(row, col), curr.dist + 1);
q.addLast(adjCell);
// Update the distance
// of the adjacent cells
d[row][col] = curr.dist + 1;
}
}
}
// If the destination
// is not reachable
if (!ok)
System.out.println(-1);
}
// Driver Code
public static void main(String[] args)
{
char mat[][] = { { '0', '1', '0', '1' },
{ '1', '0', '1', '1' },
{ '0', '1', '1', '1' },
{ '1', '1', '1', '0' } };
ROW = mat.length;
COL = mat[0].length;
Point src = new Point(0, 3);
Point dest = new Point(3, 0);
pathMoves(mat, src, dest);
}
}
// This code is contributed by Kingash
Python3
# Python3 program for the above approach
from collections import deque
# Stores the coordinates
# of the matrix cell
class Point:
def __init__(self, xx, yy):
self.x = xx
self.y = yy
# Stores coordinates of
# a cell and its distance
class Node:
def __init__(self, P, d):
self.pt = P
self.dist = d
# Check if the given cell is valid or not
def isValid(row, col):
return (row >= 0) and (col >= 0) and (row < 4) and (col < 4)
# Stores the moves of the directions of adjacent cells
dRow = [-1, 0, 0, 1]
dCol = [0, -1, 1, 0]
# Function to find the shortest path from the
# source to destination in the given matrix
def pathMoves(mat, src, dest):
# Stores the distance for each
# cell from the source cell
d = [[ -1 for i in range(4)] for i in range(4)]
# Distance of source cell is 0
d[src.x][src.y] = 0
# Initialize a visited array
visited = [[ False for i in range(4)] for i in range(4)]
# memset(visited, false, sizeof visited)
# Mark source cell as visited
visited[src.x][src.y] = True
# Create a queue for BFS
q = deque()
# Distance of source cell is 0
s = Node(src, 0)
# Enqueue source cell
q.append(s)
# Keeps track of whether
# destination is reached or not
ok = False
# Iterate until queue is not empty
while (len(q)>0):
# Deque front of the queue
curr = q.popleft()
pt = curr.pt
# If the destination cell is
# reached, then find the path
if (pt.x == dest.x and pt.y == dest.y):
xx, yy = pt.x, pt.y
dist = curr.dist
# Assign the distance of
# destination to the
# distance matrix
d[pt.x][pt.y] = dist
# Stores the smallest path
pathmoves = ""
# Iterate until source is reached
while (xx != src.x or yy != src.y):
# Append D
if (xx > 0 and d[xx - 1][yy] == dist - 1):
pathmoves += 'D'
xx -= 1
# Append U
if (xx < 4 - 1 and d[xx + 1][yy] == dist - 1):
pathmoves += 'U'
xx += 1
# Append R
if (yy > 0 and d[xx][yy - 1] == dist - 1):
pathmoves += 'R'
yy -= 1
# Append L
if (yy < 4 - 1 and d[xx][yy + 1] == dist - 1):
pathmoves += 'L'
yy += 1
dist -= 1
# Reverse the backtracked path
pathmoves = pathmoves[::-1]
print(pathmoves, end = "")
ok = True
break
# Pop the start of queue
# q.pop()
# Explore all adjacent directions
for i in range(4):
row = pt.x + dRow[i]
col = pt.y + dCol[i]
# If the current cell is valid
# cell and can be traversed
if (isValid(row, col) and (mat[row][col] == '1' or mat[row][col] == 's' or mat[row][col] == 'd') and (not visited[row][col])):
# Mark the adjacent cells as visited
visited[row][col] = True
# Enque the adjacent cells
adjCell = Node( Point(row, col), curr.dist + 1)
q.append(adjCell)
# Update the distance
# of the adjacent cells
d[row][col] = curr.dist + 1
# If the destination
# is not reachable
if (not ok):
print(-1)
# Driver Code
if __name__ == '__main__':
mat =[ ['0', '1', '0', '1'],
[ '1', '0', '1', '1'],
[ '0', '1', '1', '1'],
[ '1', '1', '1', '0']]
src = Point(0, 3)
dest = Point(3, 0)
pathMoves(mat, src, dest)
# This code is contributed by mohit kumar 29.
C#
// C# program for the above approach
using System;
using System.Collections.Generic;
class GFG{
static int ROW;
static int COL;
// Stores the coordinates
// of the matrix cell
class Point
{
public int x, y;
};
static Point newPoint(int x, int y)
{
Point temp = new Point();
temp.x = x;
temp.y = y;
return temp;
}
// Stores coordinates of
// a cell and its distance
class Node
{
public Point pt;
public int dist;
};
static Node newNode(Point p, int dist)
{
Node temp = new Node();
temp.pt = p;
temp.dist = dist;
return temp;
}
// Check if the given cell is valid or not
static bool isValid(int row, int col)
{
return (row >= 0) && (col >= 0) &&
(row < ROW) && (col < COL);
}
// Stores the moves of the directions
// of adjacent cells
static int []dRow = { -1, 0, 0, 1 };
static int []dCol = { 0, -1, 1, 0 };
// Function to find the shortest path from the
// source to destination in the given matrix
static void pathMoves(char [,]mat, Point src,
Point dest)
{
// Stores the distance for each
// cell from the source cell
int [,]d = new int[ROW, COL];
for(int i = 0; i < ROW; i++)
{
for(int j = 0; j < COL; j++)
d[i, j] = -1;
}
// Distance of source cell is 0
d[src.x, src.y] = 0;
// Initialize a visited array
bool [,]visited = new bool[ROW, COL];
// Mark source cell as visited
visited[src.x, src.y] = true;
// Create a queue for BFS
Queue q = new Queue();
// Distance of source cell is 0
Node s = newNode(src, 0);
// Enqueue source cell
q.Enqueue(s);
// Keeps track of whether
// destination is reached or not
bool ok = false;
// Iterate until queue is not empty
while (q.Count > 0)
{
// Deque front of the queue
Node curr = q.Peek();
q.Dequeue();
Point pt = curr.pt;
// If the destination cell is
// reached, then find the path
if (pt.x == dest.x && pt.y == dest.y)
{
int xx = pt.x, yy = pt.y;
int dist = curr.dist;
// Assign the distance of
// destination to the
// distance matrix
d[pt.x,pt.y] = dist;
// Stores the smallest path
string pathmoves = "";
// Iterate until source is reached
while (xx != src.x || yy != src.y)
{
// Append D
if (xx > 0 &&
d[xx - 1, yy] == dist - 1)
{
pathmoves += 'D';
xx--;
}
// Append U
if (xx < ROW - 1 &&
d[xx + 1, yy] == dist - 1)
{
pathmoves += 'U';
xx++;
}
// Append R
if (yy > 0 &&
d[xx, yy - 1] == dist - 1)
{
pathmoves += 'R';
yy--;
}
// Append L
if (yy < COL - 1 &&
d[xx, yy + 1] == dist - 1)
{
pathmoves += 'L';
yy++;
}
dist--;
}
// Print reverse the backtracked path
for(int i = pathmoves.Length - 1;
i >= 0; --i)
Console.Write(pathmoves[i]);
ok = true;
break;
}
// Pop the start of queue
if (q.Count > 0)
{
q.Peek();
q.Dequeue();
}
// Explore all adjacent directions
for(int i = 0; i < 4; i++)
{
int row = pt.x + dRow[i];
int col = pt.y + dCol[i];
// If the current cell is valid
// cell and can be traversed
if (isValid(row, col) &&
(mat[row, col] == '1' ||
mat[row, col] == 's' ||
mat[row, col] == 'd') &&
!visited[row, col])
{
// Mark the adjacent cells as visited
visited[row,col] = true;
// Enque the adjacent cells
Node adjCell = newNode(newPoint(row, col),
curr.dist + 1);
q.Enqueue(adjCell);
// Update the distance
// of the adjacent cells
d[row, col] = curr.dist + 1;
}
}
}
// If the destination
// is not reachable
if (ok == false)
Console.Write(-1);
}
// Driver Code
public static void Main()
{
char [,]mat = { { '0', '1', '0', '1' },
{ '1', '0', '1', '1' },
{ '0', '1', '1', '1' },
{ '1', '1', '1', '0' } };
ROW = mat.GetLength(0);
COL = mat.GetLength(0);
Point src = newPoint(0, 3);
Point dest = newPoint(3, 0);
pathMoves(mat, src, dest);
}
}
// This code is contributed by SURENDRA_GANGWAR
Javascript
DLDLDL
时间复杂度: O(N*M)
辅助空间: O(N*M)
如果您希望与专家一起参加现场课程,请参阅DSA 现场工作专业课程和学生竞争性编程现场课程。