给定大小为N * M的二进制矩阵mat [] []以及分别代表源单元和目标单元的整数对src和dest ,任务是找到从给定源单元通过单元到目标单元的最短移动顺序仅由1 s组成。允许的移动是向左( 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 。
- 检查弹出的节点是否是目标节点。如果发现是正确的,则使用“回溯”找到从目标单元格到源单元格的路径。
- 否则,插入当前弹出节点的所有未访问的相邻单元格,其距离为(先前距离+ 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
DLDLDL
时间复杂度: O(N * M)
辅助空间: O(N * M)