考虑将一只老鼠放在n阶方阵m [] []中的(0,0)处,并且必须到达(n-1,n-1)的目的地。我们的任务是找到一个排序后的字符串数组,这些字符串表示大鼠在(n-1,n-1)处到达目的地的所有可能方向。老鼠可以移动的方向是“ U”(上),“ D”(下),“ L”(左),“ R”(右)。
例子:
Input : N = 4
1 0 0 0
1 1 0 1
0 1 0 0
0 1 1 1
Output :
DRDDRR
Input :N = 4
1 0 0 0
1 1 0 1
1 1 0 0
0 1 1 1
Output :
DDRDRR DRDDRR
Explanation:
解决方案:
方法:
- 从初始索引(即(0,0))开始,并在网格中按向下- >左侧->右侧->向上的顺序查找通过相邻单元格的有效移动(以便获得排序的路径)。
- 如果可以移动,则移动到该单元格并存储与move(D,L,R,U)对应的字符,然后再次开始寻找有效的移动,直到最后一个索引(即(n-1,n-1 )) 到达了。
- 同样,继续将这些单元格标记为已访问,并且当我们遍历该单元格的所有可能路径时,然后取消标记该单元格的其他不同路径,并从形成的路径中删除字符。
- 到达网格的最后一个索引(右下)时,然后存储遍历的路径。
下面是上述方法的实现:
C++
// C++ implementation of the above approach
#include
#define MAX 5
using namespace std;
// Function returns true if the
// move taken is valid else
// it will return false.
bool isSafe(int row, int col, int m[][MAX],
int n, bool visited[][MAX])
{
if (row == -1 || row == n || col == -1 ||
col == n || visited[row][col]
|| m[row][col] == 0)
return false;
return true;
}
// Function to print all the possible
// paths from (0, 0) to (n-1, n-1).
void printPathUtil(int row, int col, int m[][MAX],
int n, string& path, vector&
possiblePaths, bool visited[][MAX])
{
// This will check the initial point
// (i.e. (0, 0)) to start the paths.
if (row == -1 || row == n || col == -1
|| col == n || visited[row][col]
|| m[row][col] == 0)
return;
// If reach the last cell (n-1, n-1)
// then store the path and return
if (row == n - 1 && col == n - 1) {
possiblePaths.push_back(path);
return;
}
// Mark the cell as visited
visited[row][col] = true;
// Try for all the 4 directions (down, left,
// right, up) in the given order to get the
// paths in lexicographical order
// Check if downward move is valid
if (isSafe(row + 1, col, m, n, visited))
{
path.push_back('D');
printPathUtil(row + 1, col, m, n,
path, possiblePaths, visited);
path.pop_back();
}
// Check if the left move is valid
if (isSafe(row, col - 1, m, n, visited))
{
path.push_back('L');
printPathUtil(row, col - 1, m, n,
path, possiblePaths, visited);
path.pop_back();
}
// Check if the right move is valid
if (isSafe(row, col + 1, m, n, visited))
{
path.push_back('R');
printPathUtil(row, col + 1, m, n,
path, possiblePaths, visited);
path.pop_back();
}
// Check if the upper move is valid
if (isSafe(row - 1, col, m, n, visited))
{
path.push_back('U');
printPathUtil(row - 1, col, m, n,
path, possiblePaths, visited);
path.pop_back();
}
// Mark the cell as unvisited for
// other possible paths
visited[row][col] = false;
}
// Function to store and print
// all the valid paths
void printPath(int m[MAX][MAX], int n)
{
// vector to store all the possible paths
vector possiblePaths;
string path;
bool visited[n][MAX];
memset(visited, false, sizeof(visited));
// Call the utility function to
// find the valid paths
printPathUtil(0, 0, m, n, path,
possiblePaths, visited);
// Print all possible paths
for (int i = 0; i < possiblePaths.size(); i++)
cout << possiblePaths[i] << " ";
}
// Driver code
int main()
{
int m[MAX][MAX] = { { 1, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 } };
int n = sizeof(m) / sizeof(m[0]);
printPath(m, n);
return 0;
}
Java
// Java implementation of the above approach
import java.util.*;
class GFG{
// Vector to store all the possible paths
static Vector possiblePaths = new Vector<>();
static String path = "";
static final int MAX = 5;
// Function returns true if the
// move taken is valid else
// it will return false.
static boolean isSafe(int row, int col, int m[][],
int n, boolean visited[][])
{
if (row == -1 || row == n || col == -1 ||
col == n || visited[row][col] ||
m[row][col] == 0)
return false;
return true;
}
// Function to print all the possible
// paths from (0, 0) to (n-1, n-1).
static void printPathUtil(int row, int col, int m[][],
int n, boolean visited[][])
{
// This will check the initial point
// (i.e. (0, 0)) to start the paths.
if (row == -1 || row == n || col == -1 ||
col == n || visited[row][col] ||
m[row][col] == 0)
return;
// If reach the last cell (n-1, n-1)
// then store the path and return
if (row == n - 1 && col == n - 1)
{
possiblePaths.add(path);
return;
}
// Mark the cell as visited
visited[row][col] = true;
// Try for all the 4 directions (down, left,
// right, up) in the given order to get the
// paths in lexicographical order
// Check if downward move is valid
if (isSafe(row + 1, col, m, n, visited))
{
path += 'D';
printPathUtil(row + 1, col, m, n,
visited);
path = path.substring(0, path.length() - 1);
}
// Check if the left move is valid
if (isSafe(row, col - 1, m, n, visited))
{
path += 'L';
printPathUtil(row, col - 1, m, n,
visited);
path = path.substring(0, path.length() - 1);
}
// Check if the right move is valid
if (isSafe(row, col + 1, m, n, visited))
{
path += 'R';
printPathUtil(row, col + 1, m, n,
visited);
path = path.substring(0, path.length() - 1);
}
// Check if the upper move is valid
if (isSafe(row - 1, col, m, n, visited))
{
path += 'U';
printPathUtil(row - 1, col, m, n,
visited);
path = path.substring(0, path.length() - 1);
}
// Mark the cell as unvisited for
// other possible paths
visited[row][col] = false;
}
// Function to store and print
// all the valid paths
static void printPath(int m[][], int n)
{
boolean [][]visited = new boolean[n][MAX];
// Call the utility function to
// find the valid paths
printPathUtil(0, 0, m, n, visited);
// Print all possible paths
for(int i = 0; i < possiblePaths.size(); i++)
System.out.print(possiblePaths.get(i) + " ");
}
// Driver code
public static void main(String[] args)
{
int m[][] = { { 1, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 } };
int n = m.length;
printPath(m, n);
}
}
// This code is contributed by gauravrajput1
Python3
# Python3 implementation of the above approach
from typing import List
MAX = 5
# Function returns true if the
# move taken is valid else
# it will return false.
def isSafe(row: int, col: int,
m: List[List[int]], n: int,
visited: List[List[bool]]) -> bool:
if (row == -1 or row == n or
col == -1 or col == n or
visited[row][col] or m[row][col] == 0):
return False
return True
# Function to print all the possible
# paths from (0, 0) to (n-1, n-1).
def printPathUtil(row: int, col: int,
m: List[List[int]],
n: int, path: str,
possiblePaths: List[str],
visited: List[List[bool]]) -> None:
# This will check the initial point
# (i.e. (0, 0)) to start the paths.
if (row == -1 or row == n or
col == -1 or col == n or
visited[row][col] or m[row][col] == 0):
return
# If reach the last cell (n-1, n-1)
# then store the path and return
if (row == n - 1 and col == n - 1):
possiblePaths.append(path)
return
# Mark the cell as visited
visited[row][col] = True
# Try for all the 4 directions (down, left,
# right, up) in the given order to get the
# paths in lexicographical order
# Check if downward move is valid
if (isSafe(row + 1, col, m, n, visited)):
path += 'D'
printPathUtil(row + 1, col, m, n,
path, possiblePaths, visited)
path = path[:-1]
# Check if the left move is valid
if (isSafe(row, col - 1, m, n, visited)):
path += 'L'
printPathUtil(row, col - 1, m, n,
path, possiblePaths, visited)
path = path[:-1]
# Check if the right move is valid
if (isSafe(row, col + 1, m, n, visited)):
path += 'R'
printPathUtil(row, col + 1, m, n,
path, possiblePaths, visited)
path = path[:-1]
# Check if the upper move is valid
if (isSafe(row - 1, col, m, n, visited)):
path += 'U'
printPathUtil(row - 1, col, m, n,
path, possiblePaths, visited)
path = path[:-1]
# Mark the cell as unvisited for
# other possible paths
visited[row][col] = False
# Function to store and print
# all the valid paths
def printPath(m: List[List[int]], n: int) -> None:
# vector to store all the possible paths
possiblePaths = []
path = ""
visited = [[False for _ in range(MAX)]
for _ in range(n)]
# Call the utility function to
# find the valid paths
printPathUtil(0, 0, m, n, path,
possiblePaths, visited)
# Print all possible paths
for i in range(len(possiblePaths)):
print(possiblePaths[i], end = " ")
# Driver code
if __name__ == "__main__":
m = [ [ 1, 0, 0, 0, 0 ],
[ 1, 1, 1, 1, 1 ],
[ 1, 1, 1, 0, 1 ],
[ 0, 0, 0, 0, 1 ],
[ 0, 0, 0, 0, 1 ] ]
n = len(m)
printPath(m, n)
# This code is contributed by sanjeev2552
C#
// C# implementation of the above approach
using System;
using System.Collections.Generic;
class GFG{
// List to store all the possible paths
static List possiblePaths = new List();
static String path = "";
static readonly int MAX = 5;
// Function returns true if the
// move taken is valid else
// it will return false.
static bool isSafe(int row, int col, int [,]m,
int n, bool [,]visited)
{
if (row == -1 || row == n || col == -1 ||
col == n || visited[row,col] ||
m[row,col] == 0)
return false;
return true;
}
// Function to print all the possible
// paths from (0, 0) to (n-1, n-1).
static void printPathUtil(int row, int col, int [,]m,
int n, bool [,]visited)
{
// This will check the initial point
// (i.e. (0, 0)) to start the paths.
if (row == -1 || row == n || col == -1 ||
col == n || visited[row,col] ||
m[row,col] == 0)
return;
// If reach the last cell (n-1, n-1)
// then store the path and return
if (row == n - 1 && col == n - 1)
{
possiblePaths.Add(path);
return;
}
// Mark the cell as visited
visited[row,col] = true;
// Try for all the 4 directions (down, left,
// right, up) in the given order to get the
// paths in lexicographical order
// Check if downward move is valid
if (isSafe(row + 1, col, m, n, visited))
{
path += 'D';
printPathUtil(row + 1, col, m, n,
visited);
path = path.Substring(0, path.Length - 1);
}
// Check if the left move is valid
if (isSafe(row, col - 1, m, n, visited))
{
path += 'L';
printPathUtil(row, col - 1, m, n,
visited);
path = path.Substring(0, path.Length - 1);
}
// Check if the right move is valid
if (isSafe(row, col + 1, m, n, visited))
{
path += 'R';
printPathUtil(row, col + 1, m, n,
visited);
path = path.Substring(0, path.Length - 1);
}
// Check if the upper move is valid
if (isSafe(row - 1, col, m, n, visited))
{
path += 'U';
printPathUtil(row - 1, col, m, n,
visited);
path = path.Substring(0, path.Length - 1);
}
// Mark the cell as unvisited for
// other possible paths
visited[row,col] = false;
}
// Function to store and print
// all the valid paths
static void printPath(int [,]m, int n)
{
bool [,]visited = new bool[n,MAX];
// Call the utility function to
// find the valid paths
printPathUtil(0, 0, m, n, visited);
// Print all possible paths
for(int i = 0; i < possiblePaths.Count; i++)
Console.Write(possiblePaths[i] + " ");
}
// Driver code
public static void Main(String[] args)
{
int [,]m = { { 1, 0, 0, 0, 0 },
{ 1, 1, 1, 1, 1 },
{ 1, 1, 1, 0, 1 },
{ 0, 0, 0, 0, 1 },
{ 0, 0, 0, 0, 1 } };
int n = m.GetLength(0);
printPath(m, n);
}
}
// This code is contributed by gauravrajput1
输出:
DDRRURRDDD DDRURRRDDD DRDRURRDDD DRRRRDDD
复杂度分析:
- 时间复杂度:O(3 ^(n ^ 2))。
由于每个单元中有N ^ 2个单元,因此有3个未访问的相邻单元。因此,时间复杂度为O(3 ^(N ^ 2)。 - 辅助空间: O(3 ^(n ^ 2))。
由于答案中最多可以有3 ^(n ^ 2)个像元,因此空间复杂度为O(3 ^(n ^ 2))。