Find length of the longest consecutive path from a given starting character - GeeksforGeeks
Given a matrix of characters. Find length of the longest path from a given character, such that all characters in the path are consecutive to each other, i.e., every character in path is next to previous in alphabetical order. It is allowed to move in all 8 directions from a cell.
Find the longest path in a matrix with given constraints
Read full article from Find length of the longest consecutive path from a given starting character - GeeksforGeeks
Given a matrix of characters. Find length of the longest path from a given character, such that all characters in the path are consecutive to each other, i.e., every character in path is next to previous in alphabetical order. It is allowed to move in all 8 directions from a cell.
Input: mat[][] = { {a, c, d}, {h, b, e}, {i, g, f}} Starting Point = 'e' Output: 5 If starting point is 'e', then longest path with consecutive characters is "e f g h i". Input: mat[R][C] = { {b, e, f}, {h, d, a}, {i, c, a}}; Starting Point = 'b' Output: 1 'c' is not present in all adjacent cells of 'b'
Do Depth First Search (DFS) from all occurrences to find all consecutive paths. While doing DFS, we may encounter many subproblems again and again. So we use dynamic programming to store results of subproblems.
// tool matrices to recur for adjacent cells.
int
x[] = {0, 1, 1, -1, 1, 0, -1, -1};
int
y[] = {1, 0, 1, 1, -1, -1, 0, -1};
// Used to keep track of visited cells.
bool
visited[R][C];
// dp[i][j] Stores length of longest consecutive path
// starting at arr[i][j].
int
dp[R][C];
// check whether mat[i][j] is a valid cell or not.
bool
isvalid(
int
i,
int
j)
{
if
(i < 0 || j < 0 || i >= R || j >= C)
return
false
;
return
true
;
}
// Check whether current character is adjacent to previous
// character (character processed in parent call) or not.
bool
isadjacent(
char
prev,
char
curr)
{
return
((curr - prev) == 1);
}
// i, j are the indices of the current cell and prev is the
// character processed in the parent call.. also mat[i][j]
// is our current character.
int
getLenUtil(
char
mat[R][C],
int
i,
int
j,
char
prev)
{
// If this cell is not valid or current character is not
// adjacent to previous one (e.g. d is not adjacent to b )
// or if this cell is already included in the path than return 0.
if
(!isvalid(i, j) || !isadjacent(prev, mat[i][j]) || visited[i][j])
return
0;
// If this subproblem is already solved , return the answer
if
(dp[i][j] != -1)
return
dp[i][j];
int
ans = 0;
// Initialize answer
// mark current node, so it does not get included again.
visited[i][j] =
true
;
// recur for paths with differnt adjacent cells and store
// the length of longest path.
for
(
int
k=0; k<8; k++)
ans = max(ans, 1 + getLenUtil(mat, i + x[k],
j + y[k], mat[i][j]));
// unmark current node so can be processed later as part of
// some another path if possible
visited[i][j] =
false
;
// save the answer and return
return
dp[i][j] = ans;
}
// Returns length of the longest path with all characters consecutive
// to each other. This function first initializes dp array that
// is used to store results of subproblems, then it calls
// recursive DFS based function getLenUtil() to find max length path
int
getLen(
char
mat[R][C],
char
s)
{
memset
(dp, -1,
sizeof
dp);
int
ans = 0;
for
(
int
i=0; i<R; i++)
{
for
(
int
j=0; j<C; j++)
{
// check for each possible starting point
if
(mat[i][j] == s) {
// recur for all eight adjacent cells
for
(
int
k=0; k<8; k++)
ans = max(ans, 1 + getLenUtil(mat,
i + x[k], j + y[k], s));
}
}
}
return
ans;
}
Find the longest path in a matrix with given constraints
Given a n*n matrix where numbers all numbers are distinct and are distributed from range 1 to n2, find the maximum length path (starting from any cell) such that all cells along the path are increasing order with a difference of 1.
We can move in 4 directions from a given cell (i, j), i.e., we can move to (i+1, j) or (i, j+1) or (i-1, j) or (i, j-1) with the condition that the adjacent
Input: mat[][] = {{1, 2, 9} {5, 3, 8} {4, 6, 7}} Output: 4 The longest path is 6-7-8-9.
The idea is simple, we calculate longest path beginning with every cell. Once we have computed longest for all cells, we return maximum of all longest paths. One important observation in this approach is many overlapping subproblems. Therefore this problem can be optimally solved using Dynamic Programming.
// Returns length of the longest path beginning with mat[i][j].
// This function mainly uses lookup table dp[n][n]
int
findLongestFromACell(
int
i,
int
j,
int
mat[n][n],
int
dp[n][n])
{
// Base case
if
(i<0 || i>=n || j<0 || j>=n)
return
0;
// If this subproblem is already solved
if
(dp[i][j] != -1)
return
dp[i][j];
// Since all numbers are unique and in range from 1 to n*n,
// there is atmost one possible direction from any cell
if
((mat[i][j] +1) == mat[i][j+1])
return
dp[i][j] = 1 + findLongestFromACell(i,j+1,mat,dp);
if
(mat[i][j] +1 == mat[i][j-1])
return
dp[i][j] = 1 + findLongestFromACell(i,j-1,mat,dp);
if
(mat[i][j] +1 == mat[i-1][j])
return
dp[i][j] = 1 + findLongestFromACell(i-1,j,mat,dp);
if
(mat[i][j] +1 == mat[i+1][j])
return
dp[i][j] = 1 + findLongestFromACell(i+1,j,mat,dp);
// If none of the adjacent fours is one greater
return
dp[i][j] = 1;
}
// Returns length of the longest path beginning with any cell
int
finLongestOverAll(
int
mat[n][n])
{
int
result = 1;
// Initialize result
// Create a lookup table and fill all entries in it as -1
int
dp[n][n];
memset
(dp, -1,
sizeof
dp);
// Compute longest path beginning from all cells
for
(
int
i=0; i<n; i++)
{
for
(
int
j=0; j<n; j++)
{
if
(dp[i][j] == -1)
findLongestFromACell(i, j, mat, dp);
// Update result if needed
result = max(result, dp[i][j]);
}
}
return
result;
}