Find length of the longest consecutive path from a given starting character

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.

matrix

Example

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'
 

We strongly recommend you to minimize your browser and try this yourself first.

The idea is to first search given starting character in the given matrix. 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.



Below is the implementation of above idea.

C++

// C++ program to find the longest consecutive path
#include<bits/stdc++.h>
#define R 3
#define C 3
using namespace std;

// 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};

// 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]))
         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

    // 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]));

    // 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;
}

// Driver program
int main() {

    char mat[R][C] = { {'a','c','d'},
                     { 'h','b','a'},
                     { 'i','g','f'}};

    cout << getLen(mat, 'a') << endl;
    cout << getLen(mat, 'e') << endl;
    cout << getLen(mat, 'b') << endl;
    cout << getLen(mat, 'f') << endl;
    return 0;
}

Java

class path
{
    // tool matrices to recur for adjacent cells.
    static int x[] = {0, 1, 1, -1, 1, 0, -1, -1};
    static int y[] = {1, 0, 1, 1, -1, -1, 0, -1};
    static int R = 3;
    static int C = 3;
    // dp[i][j] Stores length of longest consecutive path
    // starting at arr[i][j].
    static int dp[][] = new int[R][C];
     
    // check whether mat[i][j] is a valid cell or not.
    static boolean 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.
    static boolean 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.
    static int getLenUtil(char mat[][], 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]))
             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
     
        // recur for paths with differnt adjacent cells and store
        // the length of longest path.
        for (int k=0; k<8; k++)
          ans = Math.max(ans, 1 + getLenUtil(mat, i + x[k],
                                       j + y[k], mat[i][j]));
     
        // 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
    static int getLen(char mat[][], char s)
    {
        //assigning all dp values to -1
        for(int i = 0;i<R;++i)
            for(int j = 0;j<C;++j)
                dp[i][j] = -1;
        
        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 = Math.max(ans, 1 + getLenUtil(mat,
                                        i + x[k], j + y[k], s));
                }
            }
        }
        return ans;
    }
    public static void main(String args[])
    {
        char mat[][] = { {'a','c','d'},
                           { 'h','b','a'},
                           { 'i','g','f'}};
 
        System.out.println(getLen(mat, 'a') );
        System.out.println(getLen(mat, 'e') );
        System.out.println(getLen(mat, 'b') );
        System.out.println(getLen(mat, 'f') );
    }
}/* This code is contributed by Rajat Mishra */

C#

// C# program to find the longest consecutive path
using System;

class GFG {
    
    // tool matrices to recur for adjacent cells.
    static int []x = {0, 1, 1, -1, 1, 0, -1, -1};
    static int []y = {1, 0, 1, 1, -1, -1, 0, -1};
    static int R = 3;
    static int C = 3;
    
    // dp[i][j] Stores length of longest 
    // consecutive path starting at arr[i][j].
    static int [,]dp = new int[R,C];
    
    // check whether mat[i][j] is a valid
    // cell or not.
    static 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.
    static 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.
    static int getLenUtil(char [,]mat, 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]))
            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
    
        // recur for paths with differnt adjacent
        // cells and store the length of 
        // longest path.
        for (int k = 0; k < 8; k++)
        ans = Math.Max(ans, 1 + getLenUtil(mat,
                   i + x[k], j + y[k], mat[i,j]));
    
        // 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
    static int getLen(char [,]mat, char s)
    {
        
        //assigning all dp values to -1
        for(int i = 0; i < R; ++i)
            for(int j = 0; j < C; ++j)
                dp[i,j] = -1;
        
        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 = Math.Max(ans, 1 + 
                             getLenUtil(mat, i + 
                             x[k], j + y[k], s));
                }
            }
        }
        return ans;
    }
    
    // Driver code`
    public static void Main()
    {
        char [,]mat = { {'a','c','d'},
                        { 'h','b','a'},
                        { 'i','g','f'}};

        Console.WriteLine(getLen(mat, 'a') );
        Console.WriteLine(getLen(mat, 'e') );
        Console.WriteLine(getLen(mat, 'b') );
        Console.WriteLine(getLen(mat, 'f') );
    }
}

// This code is contributed by nitin mittal.


Output:

4
0
3
4

Thanks to Gaurav Ahirwar for above solution.

Please write comments if you find anything incorrect, or you want to share more information about the topic discussed above



My Personal Notes arrow_drop_up

Improved By : nitin mittal




Article Tags :
Please write to us at contribute@geeksforgeeks.org to report any issue with the above content.

Recommended Posts:



3.4 Average Difficulty : 3.4/5.0
Based on 63 vote(s)






User Actions