Code360 powered by Coding Ninjas X Naukri.com. Code360 powered by Coding Ninjas X Naukri.com

Longest String Chain

Moderate
0/80
profile
Contributed by
43 upvotes
Asked in companies
FacebookMathworksGoogle

Problem statement

You are given an array 'arr' of strings, where each string consists of English lowercase letters.


A string chain of 'arr' is defined as:

(1) A sequence of string formed using elements of 'arr'.

(2) Every string in the sequence can be formed by inserting a lowercase English letter into the previous string (except the first string).


Find the length of the longest possible string chain of 'arr'.


Example :
Input: 'arr' = ["x", "xx", "y", "xyx"] 

Output: 3

Explanation:
The longest possible string chain is “x” -> “xx” -> “xyx”.
The length of the given chain is 3, hence the answer is 3.


Detailed explanation ( Input/output format, Notes, Images )
Input Format :
The first line of the input contains a single integer 'n' denoting the length of the 'arr'.

The next 'n' lines of the input contains elements of 'arr'.


Output Format :
Return the length of the longest possible string chain with strings chosen from the given array.


Note :
You don't need to print anything; it has already been taken care of. Just implement the function.


Sample Input 1 :
3
m 
nm 
mmm


Expected Answer :
2


Output on console :
2


Explanation For Sample Input 1 :
In this testcase, the longest possible string chain is "m" -> "nm".
The length of the given chain is 2, hence the answer is 2.


Sample Input 2 :
5
a 
bc 
ad 
adc 
bcd


Expected Answer :
3


Output on console :
3


Explanation For Sample Input 2 :
In this testcase, the longest possible string chain is “a” -> “ad” -> “adc”.
The length of the given chain is 3, hence the answer is 3.


Expected Time Complexity :
Try to solve this in O(n*n*l), where 'n' is the size of array 'arr' and 'l' is the maximum length of a string in 'arr'. 


Constraints :
1 ≤ n ≤ 300    
1 ≤ arr[i].length ≤ 16

Time limit: 1 sec
Hint

Explore all the possibilities for each word.

Approaches (3)
Recursion

The total number of states are approximately equal to N ^ N. Note that state denotes a function call to ‘rec()’. In this approach, we generate all possible chains starting from ARR[I].

 

At the i’th position, we will explore the longest string chain which would be possible starting from this string(i’th). We will take the maximum of the length of all string chains possible from ‘i’ equal to 0 to ‘N’ - 1.

 

The recursion tree for ‘ARR’ = [“x”, “xx”, “y”, “xyx”] will be :

 

 

The steps are as follows :

  1. Sort the given array according to the string length in ascending order.
  2. Initialize a variable ‘ans’ to 0, this will store the length of the longest string chain.
  3. for ‘i’ in [0 . . N - 1]:
    • ‘ans’ = max(ans, rec(arr, i))
    • In rec() we go from the current string at index ‘i’ to all further strings for whom this current string at index ‘i’ can be a predecessor.
    • Initialize a variable ‘curr’ which will store length of longest string chain starting from ARR[i].
    • for ‘j’ in [i + 1 . . N - 1]:
  • if(predecessor(ARR[i], ARR[j]):
    • ‘curr’ = max(curr, 1 + rec(arr, j)).
  • Return ‘curr’.
Time Complexity

O( N ^ ( N + L ) ), where N is the length of the array and L is the max length of the string in the array.


 

For each of the strings in the array, we may have to explore all the remaining strings of the order ~N. The total number of states are approximately equal to N ^ N. Note that state denotes a function call to ‘rec()’. And every time we will also check for predecessor. 

Hence the time complexity is O( N ^ ( N + L ) ).

Space Complexity

O( N ^ 2 ), where N is the length of the array.


 

The maximum number of stack frames that could be present in memory at any point of time are ~N. And there will be N such recursive calls. Each function call take `O( N ) space and the maximum depth of the recursion tree is N.

Hence the space complexity is O( N ^ 2 ).

Code Solution
(100% EXP penalty)
Longest String Chain
All tags
Sort by
Search icon

Interview problems

that solution accepted in leetcode but in that platform 29/30 cases passes

#include <bits/stdc++.h>

int fun(int i,int j,string &s1,string &s2,vector<vector<int>>&dp1){

 

    if(j==-1 ) {

        return 1;

    }

    if(i==-1  && j>=0) return 0;

    if(dp1[i][j]!=-1) return dp1[i][j];

    int nt=fun(i-1,j,s1,s2,dp1);

    int t=0;

    if(s1[i]==s2[j]){

        t=fun(i-1,j-1,s1,s2,dp1);

    }

    return dp1[i][j]=(t || nt);

}

bool match(string &s1,string &s2){

    int n=s1.size();

    int m=s2.size();

    if((n-m)!=1) return false;

    vector<vector<int>>dp1(n+1,vector<int>(m+1,-1));

    return fun(n-1,m-1,s1,s2,dp1);

}

int fun1(int i,int j,vector<string>&arr,vector<vector<int>>&dp,int n){

    if(i==n) return 0;

    if(dp[i][j+1]!=-1) return dp[i][j+1];

    int nt=fun1(i+1,j,arr,dp,n);

    int t=-1e9;

    if(j==-1 or ((match(arr[i],arr[j])==true) )){

       t= 1+fun1(i+1,i,arr,dp,n);

    }

    return dp[i][j+1]=max(t,nt);

}

bool comp(string s1 ,string s2){

    return s1.length()<s2.length();

}

 

int longestStrChain(vector<string> &arr){

    int n=arr.size();

    sort(arr.begin(),arr.end(),comp);

    vector<vector<int>>dp(n+1,vector<int>(n+1,-1));

    return fun1(0,-1,arr,dp,n);

}

 

92 views
1 reply
0 upvotes

Interview problems

python code

from functools import cmp_to_key

from typing import List



 

def cmp(a: str, b: str) -> bool:

    if len(a) < len(b):

        return -1

    return 1



 

#  Helper function to check if string 'A' is predecessor of 'B'.

def predecessor(a: str, b: str):


 

    m = len(a)

    n = len(b)


 

    # Check if difference between length is equal to 1.

    if (n - m != 1 or m >= n):


 

        return False


 

    i = 0

    j = 0


 

    # Check if 'A' is a subsequence of 'B'.

    while (i < m and j < n):


 

        if (a[i] == b[j]):

            i += 1


 

        j += 1


 

    return i == m



 

# Helper function.

def longestStrChainHelper(arr: List[str], i: int) -> int:


 

    # Variable to store longest chain starting from string at ARR[i].

    chainLength = 1


 

    for j in range(i + 1, len(arr)):


 

        # Check if the current string is predecessor to next string.

        if (predecessor(arr[i], arr[j])):


 

            # Recursive call for the j'th index.

            chainLength = max(

                chainLength, 1 + longestStrChainHelper(arr, j))


 

    # Update the result in 'DP' array, to avoid recomputation in future.

    return chainLength



 

def longestStrChain(arr: List[str]) -> int:

    n = len(arr)


 

    # Sort 'ARR' on basis on length of strings.

    arr = sorted(arr, key=cmp_to_key(cmp))


 

    # Variable to store length of longest string chain.

    length = 0


 

    for i in range(n):

        length = max(length, longestStrChainHelper(arr, i))


 

    # Finally, return the answer.

    return length

26 views
0 replies
0 upvotes

Interview problems

Dp Strivers approach ✅✅

bool checkPossible(string &s1,string &s2)

{

if(s1.size()!=s2.size()+1) return false;

int first=0;

int second=0;

while(first<s1.size())

{

if(s1[first]==s2[second] && second<s2.size())

{

first++;

second++;

}

else{

first++;

}

}

if(first==s1.size() && second==s2.size())

{

return true;

}

return false;

}

static bool comp(string &s1,string &s2)

{

return s1.size()<s2.size();

}

int longestStrChain(vector<string> &arr){

int n=arr.size();

sort(arr.begin(),arr.end(),comp);

vector<int>dp(n,1);

int maxi=1;

for(int i=0;i<n;i++)

{

for(int prev=0;prev<i;prev++)

{

if(checkPossible(arr[i],arr[prev]) && 1+dp[prev]>dp[i])

{

dp[i]=1+dp[prev];

}

}

if(dp[i]>maxi)

{

maxi=dp[i];

}

}

return maxi;

}

234 views
0 replies
1 upvote

Interview problems

Striver's approach C++

bool check(string str1, string str2){

    if(str1.length()!=str2.length()+1) return false;

    int i=0, j=0;

    while(i<str1.length()){

        if(str1[i]==str2[j]){

            i++; j++;

        }

        else{

            i++;

        }

    }

    if(i==str1.length() and j==str2.length()) return true;

}

bool comp(string str1, string str2){

    return str1.length()<str2.length();

}

int longestStrChain(vector<string> &arr){

    int n=arr.size();

    sort(arr.begin(), arr.end(), comp);

    vector<int> dp(n, 1);

    int maxi=1;

    int lastind=0;

    for(int i=0; i<n; i++){

        for(int prev=0; prev<i; prev++){

            if(check(arr[i], arr[prev]) and 1+dp[prev]>dp[i]){

                dp[i]=1+dp[prev];

            }

        }

        if(dp[i]>maxi){

            maxi=dp[i];

        }

    }

    return maxi;

}

228 views
0 replies
0 upvotes

Interview problems

JAVA EASY SOLUTION || DYNAMIC PROGRAMMING

import java.util.*;

public class Solution {

    public static int longestStrChain(String[] arr) {

        Arrays.sort(arr,(a,b)->a.length()-b.length());

       

        int dp[] = new int[arr.length];  

        for(int i=0;i<arr.length;i++) dp[i]=1;

         int max=0;

        for(int i=0;i<arr.length;i++)

        {   

           

            for(int j=0;j<i;j++)

            {

                if(compare(arr[i],arr[j]))

                {

                    dp[i]=Math.max(dp[i],dp[j]+1);

                }

            }

            max=Math.max(max,dp[i]);

        }

        return max;

    }

    public static boolean compare(String str1 , String str2)

    {   

            if(Math.abs(str1.length()-str2.length())!=1) return false;

             

            if(str1.length()>str2.length())

            {

             int i=0;

             int j=0;

             while(i<str1.length() && j<str2.length())

             {

                if(str1.charAt(i)==str2.charAt(j) )

                {

                    i++;

                    j++;

                }

                else{

                    i++;

                }

             }

            

            if((i==str1.length() && j==str2.length()) || (i+1 == str1.length() && j== str2.length()))

             { 

                return true;

             }

 

            }

             return false;

            

    }

}
103 views
0 replies
0 upvotes

Interview problems

for Samarth

#include<bits/stdc++.h> int lcs(string X, string Y, int m, int n) {      int L[m + 1][n + 1];       for (int i = 0; i <= m; i++) {        for (int j = 0; j <= n; j++) {            if (i == 0 || j == 0)                L[i][j] = 0;            else if (X[i - 1] == Y[j - 1])                L[i][j] = L[i - 1][j - 1] + 1;            else                L[i][j] = max(L[i - 1][j], L[i][j - 1]);        }    }    return L[m][n]; }

static bool cmp(string &a, string &b) {    return a.length() <= b.length(); }

int longestStrChain(vector<string> &arr){    int n = arr.size();    sort(arr.begin(), arr.end(), cmp);    vector<int> dp(n, 1);

   int ans = 1;

   for(int curr = 1; curr < n; curr++)    {        for(int prev = 0; prev < curr; prev++)        {            if((arr[curr].length() - arr[prev].length() == 0) || (arr[curr].length() - arr[prev].length() > 1))                continue;            else               {                if(lcs(arr[curr], arr[prev], arr[curr].length(), arr[prev].length()) == arr[prev].length())                {                    if(dp[curr] < 1 + dp[prev])                    {                        dp[curr] = 1 + dp[prev];                        ans = max(ans, dp[curr]);                    }                }            }        }    }    return ans; }  

43 views
1 reply
0 upvotes

Interview problems

Very easy solution using DP

#include<bits/stdc++.h>

static bool cmp(string s,string t){

    return s.size()<t.size();

}

int longestStrChain(vector<string> &arr){

    int n=arr.size();

       unordered_map<string,int>dp;

       sort(arr.begin(),arr.end(),cmp);

       int l=1;

       for(auto x:arr){

           dp[x]=1;

           for(int i=0;i<x.size();i++){

               string p=x.substr(0,i)+x.substr(i+1);

               if(dp.find(p)!=dp.end()){

                   dp[x]=max(dp[x],dp[p]+1);

                   l=max(l,dp[x]);

               }

           }

       }

       return l;

}

103 views
0 replies
0 upvotes

Interview problems

C++ | BEST SOLUTION | DYNAMIC PROGRAMING | LIS APROACH | EASY SOLUTION 🔥🔥

bool check(string &s1, string &s2){

    if (s1.size()!=s2.size()+1){

        return false;

    }

    else{

        int first=0, second=0;

        while (first<s1.size()){

            if (s1[first]==s2[second]){

                first++, second++;

            }else{

                first++;

            }

        }

        if (first==s1.size() && second==s2.size()){

            return true;

        }else{

            return false;

        }

    }

}

 

bool comp(string &s1, string &s2){

    return s1.size()<s2.size();

}

 

int longestStrChain(vector<string> &words){

    // Write your code here.

    int n=words.size();

    vector<int> dp(n, 1);

    int maxi=1;

    sort(words.begin(), words.end(), comp);

    ios_base::sync_with_stdio(false);cin.tie(NULL); cout.tie(NULL);

    for (int i=1; i<n; i++){

        for (int j=0; j<i; j++){

            if (check(words[i], words[j]) && dp[i]<dp[j]+1){

                dp[i]=dp[j]+1;

            }

        }

        maxi=max(maxi, dp[i]);

    }

    return maxi;

}

beginners

programming

tutorial

127 views
0 replies
1 upvote

Interview problems

C++ Best Optimised Solution

#include <bits/stdc++.h> 

 

bool comp(string &s1,string &s2){

return s1.size()<s2.size();

 

}

bool compare(string s1,string s2){

    if(s1.size()!=s2.size()+1) return false;

    int first=0;

    int second=0;

    while(first<s1.size()){

        if(s1[first]==s2[second]){

            first++;

            second++;

        }

        else{

            first++;

        }

 

    }

    if(second==s2.size()){

        return true;

    }

    return false;

 

}

int longestStrChain(vector<string> &arr)

{

    int n=arr.size();

    vector<int>dp(n,1);

    int maxi=1;

  sort(arr.begin(),arr.end(),comp);

  for (int i=0;i<n;i++){

      for (int prev=0;prev<i;prev++){

            if(compare(arr[i],arr[prev]) && dp[prev]+1>dp[i]){

                dp[i]=1+dp[prev];

            }

}

if(dp[i]>maxi){

          maxi=dp[i];

      }

  }

return maxi;

}

83 views
0 replies
0 upvotes

Interview problems

Python easy solution\/ Easy to code..

def check(s1,s2):
    if len(s1)!=len(s2)+1:return False
    f1,f2=0,0
    while f1<len(s1):
        if f2<len(s2) and s1[f1]==s2[f2]:
            f1+=1
            f2+=1
        else:
            f1+=1

    if f1==len(s1) and f2==len(s2):return True
    return False


def longestStrChain(arr: List[str]) -> int:
    arr=sorted(arr,key=lambda x:len(x))
    Max=0
    dp=[1]*len(arr)
    for i in range(len(arr)):
        for prev in range(0,i):
            if check(arr[i],arr[prev]) and dp[prev]+1>dp[i]:
                dp[i]=dp[prev]+1
            
        Max=max(dp[i],Max)
    return Max

USING LIS technique!!!

53 views
0 replies
0 upvotes
Full screen
Console