712573. Longest String Chain

Medium

Here is a detailed Markdown blog post for the "Longest String Chain" problem:

Longest String Chain

Summary

Given an array of strings, find the longest string chain that can be formed by appending one character at a time to each other. For example, if the input is ["a", "ab", "abc", "abcd"], the longest string chain would be ["a", "ab", "abc", "abcd"].

Detailed Explanation

To solve this problem, we will use a greedy approach. We first sort the strings by their lengths in ascending order. Then, we iterate through the sorted array and for each string, we find the maximum length of the string that can be formed by appending one character at a time to it. This is done by finding the longest string in the array that is one character longer than the current string.

Here's a step-by-step breakdown of the solution:

  1. Sort the input array of strings by their lengths in ascending order.
  2. Initialize an empty list to store the longest string chain.
  3. Iterate through the sorted array and for each string, find the maximum length of the string that can be formed by appending one character at a time to it.
  4. For each string, iterate through the remaining strings in the array and find the first string that is one character longer than the current string.
  5. If such a string is found, append it to the longest string chain.
  6. Return the longest string chain.

Here's an ASCII art diagram illustrating the process:

  +---------------+
  |         a     |
  +---------------+
          |
          |
          v
  +---------------+
  |       ab      |
  +---------------+
          |
          |
          v
  +---------------+
  |     abc       |
  +---------------+
          |
          |
          v
  +---------------+
  |   abcde      |
  +---------------+

The time complexity of this solution is O(n^2 log n), where n is the number of strings in the input array. This is because we need to sort the array, and then iterate through it to find the maximum length of the string that can be formed by appending one character at a time to each string.

The space complexity is O(n), as we need to store the longest string chain.

Optimized Solutions

Java

java
public class Main {
    public static void main(String[] args) {
        String[] strings = {"a", "ab", "abc", "abcd"};
        List<String> longestChain = longestStringChain(strings);
        System.out.println(longestChain);
    }

    public static List<String> longestStringChain(String[] strings) {
        Arrays.sort(strings, (s1, s2) -> Integer.compare(s1.length(), s2.length()));
        List<String> longestChain = new ArrayList<>();
        for (String str : strings) {
            int maxLength = 0;
            String longestStr = null;
            for (String otherStr : strings) {
                if (otherStr.length() == str.length() + 1 && isOneCharacterLonger(str, otherStr)) {
                    maxLength = Math.max(maxLength, otherStr.length());
                    longestStr = otherStr;
                }
            }
            if (maxLength > 0) {
                longestChain.add(str);
                while (!str.equals(longestStr)) {
                    str = longestStr;
                    for (String otherStr : strings) {
                        if (otherStr.length() == str.length() + 1 && isOneCharacterLonger(str, otherStr)) {
                            maxLength = Math.max(maxLength, otherStr.length());
                            longestStr = otherStr;
                        }
                    }
                }
            }
        }
        return longestChain;
    }

    public static boolean isOneCharacterLonger(String s1, String s2) {
        if (s1.length() == s2.length()) {
            return false;
        }
        for (int i = 0; i < Math.min(s1.length(), s2.length()); i++) {
            if (s1.charAt(i) != s2.charAt(i)) {
                if (s1.length() > s2.length()) {
                    return true;
                } else {
                    return false;
                }
            }
        }
        return s1.length() > s2.length();
    }
}

Python

python
def longest_string_chain(strings):
    strings.sort(key=len)
    longest_chain = []
    for str in strings:
        max_len = 0
        longest_str = None
        for other_str in strings:
            if len(other_str) == len(str) + 1 and is_one_character_longer(str, other_str):
                max_len = max(max_len, len(other_str))
                longest_str = other_str
        if max_len > 0:
            longest_chain.append(str)
            while str != longest_str:
                str = longest_str
                for other_str in strings:
                    if len(other_str) == len(str) + 1 and is_one_character_longer(str, other_str):
                        max_len = max(max_len, len(other_str))
                        longest_str = other_str
        return longest_chain

def is_one_character_longer(s1, s2):
    if len(s1) == len(s2):
        return False
    for i in range(min(len(s1), len(s2))):
        if s1[i] != s2[i]:
            if len(s1) > len(s2):
                return True
            else:
                return False
    return len(s1) > len(s2)

C++

cpp
#include <iostream>
#include <vector>
#include <string>
#include <algorithm>

using namespace std;

vector<string> longestStringChain(vector<string>& strings) {
    sort(strings.begin(), strings.end(), [](const string& s1, const string& s2) { return s1.length() < s2.length(); });
    vector<string> longestChain;
    for (string str : strings) {
        int maxLength = 0;
        string longestStr = "";
        for (string otherStr : strings) {
            if (otherStr.length() == str.length() + 1 && isOneCharacterLonger(str, otherStr)) {
                maxLength = max(maxLength, otherStr.length());
                longestStr = otherStr;
            }
        }
        if (maxLength > 0) {
            longestChain.push_back(str);
            while (!str.equals(longestStr)) {
                str = longestStr;
                for (string otherStr : strings) {
                    if (otherStr.length() == str.length() + 1 && isOneCharacterLonger(str, otherStr)) {
                        maxLength = max(maxLength, otherStr.length());
                        longestStr = otherStr;
                    }
                }
            }
        }
    }
    return longestChain;
}

bool isOneCharacterLonger(const string& s1, const string& s2) {
    if (s1.length() == s2.length()) {
        return false;
    }
    for (int i = 0; i < min(s1.length(), s2.length()); i++) {
        if (s1[i] != s2[i]) {
            if (s1.length() > s2.length()) {
                return true;
            } else {
                return false;
            }
        }
    }
    return s1.length() > s2.length();
}

int main() {
    vector<string> strings = {"a", "ab", "abc", "abcd"};
    vector<string> longestChain = longestStringChain(strings);
    for (string str : longestChain) {
        cout << str << endl;
    }
    return 0;
}

JavaScript

javascript
function longestStringChain(strings) {
    strings.sort((s1, s2) => s1.length - s2.length);
    let longestChain = [];
    for (let str of strings) {
        let maxLength = 0;
        let longestStr = "";
        for (let otherStr of strings) {
            if (otherStr.length === str.length + 1 && isOneCharacterLonger(str, otherStr)) {
                maxLength = Math.max(maxLength, otherStr.length);
                longestStr = otherStr;
            }
        }
        if (maxLength > 0) {
            longestChain.push(str);
            while (!str.equals(longestStr)) {
                str = longestStr;
                for (let otherStr of strings) {
                    if (otherStr.length === str.length + 1 && isOneCharacterLonger(str, otherStr)) {
                        maxLength = Math.max(maxLength, otherStr.length);
                        longestStr = otherStr;
                    }
                }
            }
        }
    }
    return longestChain;
}

function isOneCharacterLonger(s1, s2) {
    if (s1.length === s2.length) {
        return false;
    }
    for (let i = 0; i < Math.min(s1.length, s2.length); i++) {
        if (s1[i] !== s2[i]) {
            if (s1.length > s2.length) {
                return true;
            } else {
                return false;
            }
        }
    }
    return s1.length > s2.length;
}

let strings = ["a", "ab", "abc", "abcd"];
let longestChain = longestStringChain(strings);
for (let str of longestChain) {
    console.log(str);
}
View on GeeksforGeeks

Not available

DevExCode

Master coding interviews with Leetcode, system design, TechBit, QuickLearn, DevTips, Tech Battles, and career services.

© 2026 DevExCode. All rights reserved.