矩阵中从特定源单元格到目标单元格的最长路径
给定一个矩阵mat[][],以及源节点和目标节点的坐标,任务是找到从源节点到目标节点的最长路径的长度。
例子:
Input: mat[][] = {{5, 6, 7, 8}, {4, 1, 0, 9}, {3, 2, 11, 10}}, src = {1, 1}, dest = {2, 2}
Output: 11
Explanation: The longest path between the coordinates (1, 1) and (2, 2) has 11 nodes and the path is given as 1 -> 2 -> 3 -> 4 -> 5 -> 6 -> 7 -> 8 -> 9 -> 10 -> 11.
Input: mat = {{5, 4, 1, 0}, {6, 3, 2, 0}, {7, 8, 9, 0}}, src = {0, 1}, dest = {2, 2}
Output: 12
方法:给定的问题可以使用递归和回溯来解决。这个想法是使用深度优先搜索来探索从源到目的地的每条路径,并计算路径之间的节点数。请按照以下步骤解决问题:
- 从源节点到目标节点应用深度优先搜索
- 沿上述四个方向遍历,并在每个节点处增加行进的节点数。
- 在visited[][]数组中将当前路径中的节点标记为已访问,并在所有四个方向上递归调用未访问的节点。
- 到达目的地节点后,更新到达目的地所需经过的最大节点数。
- 保持所有路径上的最大节点数,这是所需的答案。
下面是上述方法的实现:
C++
// C++ implementation for the above approach
#include
using namespace std;
// Depth-First-Search function for
// recursion and backtracking
void dfs(vector> mat, int maxi[],
vector> visited, int len,
int i, int j, int dest[])
{
// Return if current node is already
// visited or it is out of bounds
if (i < 0 || j < 0 || i == mat.size() || j == mat[0].size() || visited[i][j])
return;
// If reached the destination
// then update maximum length
if (i == dest[0] && j == dest[1])
{
// Update max
maxi[0] = max(maxi[0], len);
return;
}
// Mark current node as visited
visited[i][j] = true;
// Recursive call in all
// the four directions
dfs(mat, maxi, visited, len + 1, i, j - 1, dest);
dfs(mat, maxi, visited, len + 1, i + 1, j, dest);
dfs(mat, maxi, visited, len + 1, i - 1, j, dest);
dfs(mat, maxi, visited, len + 1, i, j + 1, dest);
// Mark current cell as unvisited
visited[i][j] = false;
}
// Function to find the length of
// the longest path between two nodes
int longestPath(vector> mat, int src[],
int dest[])
{
// Initialize a variable to
// calculate longest path
int maxi[1];
maxi[0] = 0;
// Number of rows
int N = mat.size();
// Number of columns
int M = mat[0].size();
// Initialize a boolean matrix to
// keep track of the cells visited
vector> visited(N, vector(M, 0));
// Call the depth-first-search
dfs(mat, maxi, visited, 0, src[0], src[1], dest);
// Return the answer
return maxi[0] + 1;
}
// Driver code
int main()
{
vector> mat = {{5, 6, 7, 8},
{4, 1, 0, 9},
{3, 2, 11, 10}};
int src[] = {1, 1};
int dest[] = {2, 2};
cout << (longestPath(mat, src, dest));
}
// This code is contributed by Potta Lokesh
Java
// Java implementation for the above approach
import java.io.*;
import java.lang.Math;
import java.util.*;
// Driver code
class GFG {
// Function to find the length of
// the longest path between two nodes
public static int longestPath(int[][] mat, int[] src,
int[] dest)
{
// Initialize a variable to
// calculate longest path
int[] max = new int[1];
// Number of rows
int N = mat.length;
// Number of columns
int M = mat[0].length;
// Initialize a boolean matrix to
// keep track of the cells visited
boolean[][] visited = new boolean[N][M];
// Call the depth-first-search
dfs(mat, max, visited, 0, src[0], src[1], dest);
// Return the answer
return max[0] + 1;
}
// Depth-First-Search function for
// recursion and backtracking
public static void dfs(int[][] mat, int[] max,
boolean[][] visited, int len,
int i, int j, int[] dest)
{
// Return if current node is already
// visited or it is out of bounds
if (i < 0 || j < 0 || i == mat.length
|| j == mat[0].length || visited[i][j])
return;
// If reached the destination
// then update maximum length
if (i == dest[0] && j == dest[1]) {
// Update max
max[0] = Math.max(max[0], len);
return;
}
// Mark current node as visited
visited[i][j] = true;
// Recursive call in all
// the four directions
dfs(mat, max, visited, len + 1, i, j - 1, dest);
dfs(mat, max, visited, len + 1, i + 1, j, dest);
dfs(mat, max, visited, len + 1, i - 1, j, dest);
dfs(mat, max, visited, len + 1, i, j + 1, dest);
// Mark current cell as unvisited
visited[i][j] = false;
}
// Driver code
public static void main(String[] args)
{
int[][] mat = { { 5, 6, 7, 8 },
{ 4, 1, 0, 9 },
{ 3, 2, 11, 10 } };
int[] src = { 1, 1 };
int[] dest = { 2, 2 };
System.out.println(longestPath(mat, src, dest));
}
}
Python3
# Python 3 implementation for the above approach
# Depth-First-Search function for
# recursion and backtracking
def dfs(mat, maxi, visited, length, i, j, dest):
# Return if current node is already
# visited or it is out of bounds
if (i < 0 or j < 0 or i == len(mat) or j == len(mat[0]) or visited[i][j]):
return
# If reached the destination
# then update maximum length
if (i == dest[0] and j == dest[1]):
# Update max
maxi[0] = max(maxi[0], length)
return
# Mark current node as visited
visited[i][j] = True
# Recursive call in all
# the four directions
dfs(mat, maxi, visited, length + 1, i, j - 1, dest)
dfs(mat, maxi, visited, length + 1, i + 1, j, dest)
dfs(mat, maxi, visited, length + 1, i - 1, j, dest)
dfs(mat, maxi, visited, length + 1, i, j + 1, dest)
# Mark current cell as unvisited
visited[i][j] = False
# Function to find the length of
# the longest path between two nodes
def longestPath(mat, src,
dest):
# Initialize a variable to
# calculate longest path
maxi = [0]*1
maxi[0] = 0
# Number of rows
N = len(mat)
# Number of columns
M = len(mat[0])
# Initialize a boolean matrix to
# keep track of the cells visited
visited = [[0 for x in range(M)] for y in range(N)]
# Call the depth-first-search
dfs(mat, maxi, visited, 0, src[0], src[1], dest)
# Return the answer
return maxi[0] + 1
# Driver code
if __name__ == "__main__":
mat = [[5, 6, 7, 8],
[4, 1, 0, 9],
[3, 2, 11, 10]]
src = [1, 1]
dest = [2, 2]
print(longestPath(mat, src, dest))
# This code is contributed by ukasp.
C#
// C# implementation for the above approach
using System;
// Driver code
class GFG {
// Function to find the length of
// the longest path between two nodes
public static int longestPath(int[,] mat, int[] src,
int[] dest)
{
// Initialize a variable to
// calculate longest path
int[] max = new int[1];
// Number of rows
int N = mat.GetLength(0);
// Number of columns
int M = mat.GetLength(1);
// Initialize a boolean matrix to
// keep track of the cells visited
bool[,] visited = new bool[N, M];
// Call the depth-first-search
dfs(mat, max, visited, 0, src[0], src[1], dest);
// Return the answer
return max[0] + 1;
}
// Depth-First-Search function for
// recursion and backtracking
public static void dfs(int[,] mat, int[] max,
bool[,] visited, int len,
int i, int j, int[] dest)
{
// Return if current node is already
// visited or it is out of bounds
if (i < 0 || j < 0 || i == mat.GetLength(0)
|| j == mat.GetLength(1)|| visited[i, j])
return;
// If reached the destination
// then update maximum length
if (i == dest[0] && j == dest[1]) {
// Update max
max[0] = Math.Max(max[0], len);
return;
}
// Mark current node as visited
visited[i, j] = true;
// Recursive call in all
// the four directions
dfs(mat, max, visited, len + 1, i, j - 1, dest);
dfs(mat, max, visited, len + 1, i + 1, j, dest);
dfs(mat, max, visited, len + 1, i - 1, j, dest);
dfs(mat, max, visited, len + 1, i, j + 1, dest);
// Mark current cell as unvisited
visited[i, j] = false;
}
// Driver code
public static void Main()
{
int[,] mat = { { 5, 6, 7, 8 },
{ 4, 1, 0, 9 },
{ 3, 2, 11, 10 } };
int[] src = { 1, 1 };
int[] dest = { 2, 2 };
Console.Write(longestPath(mat, src, dest));
}
}
// This code is contributed by Samim Hossain Mondal.
Javascript
输出
11
时间复杂度: O(4 (N+M) )
辅助空间: O(N * M)