Close Menu
    Code and Debug
    • Home
    • Our Courses
    • Blog
    • About Us
    • Contact Us
    Facebook X (Twitter) Instagram YouTube WhatsApp
    • Home
    • Our Courses
    • Blog
    • About Us
    • Contact Us
    Facebook Instagram YouTube LinkedIn WhatsApp
    Code and Debug – BlogCode and Debug – Blog
    Code and Debug – BlogCode and Debug – Blog
    Home»Data Structures & Algorithms»Print the Longest Common Subsequence | Build Table, Then Reconstruct
    Data Structures & Algorithms

    Print the Longest Common Subsequence | Build Table, Then Reconstruct

    Anirudh KhuranaBy Anirudh Khurana22 August 2025No Comments4 Mins Read
    Share Facebook Twitter Pinterest LinkedIn Tumblr Reddit Telegram Email
    Featured image of a question to print the Longest Common Subsequence
    Share
    Facebook Twitter LinkedIn Pinterest Email

    Given two strings text1 and text2, the goal is to print one actual Longest Common Subsequence (LCS), not just its length. An LCS is a sequence that appears in both strings in the same relative order, but not necessarily contiguously. If multiple LCS strings exist, returning any one of them is acceptable.

    Example

    text1 = "abcde", text2 = "ace"
    LCS length = 3, one LCS is "ace"
    text1 = "abc", text2 = "def"
    LCS length = 0, LCS string is ""

    Intuition and Approach

    The standard approach has two clear phases.

    1. Compute the DP table of LCS lengths
      Build a table dp of size (n+1) x (m+1) where dp[i][j] stores the LCS length for prefixes text1[:i] and text2[:j].
      Transition:
      • If text1[i-1] == text2[j-1], then dp[i][j] = 1 + dp[i-1][j-1].
      • Otherwise, dp[i][j] = max(dp[i-1][j], dp[i][j-1]).
    2. Backtrack to reconstruct one LCS string
      Start from dp[n][m] and walk backwards:
      • If characters match, that character is part of the LCS. Append it and move diagonally to (i-1, j-1).
      • If they do not match, move to the neighbor cell that has the larger LCS value.
        The path you trace yields the LCS in reverse order, so reverse the collected characters at the end.

    This method guarantees correctness because the backtrack follows exactly the choices that led to the optimal length stored in the table.


    Code Implementation

    Your provided implementation, unchanged, with brief comments added only:

    class Solution:
        def longestCommonSubsequence(self, text1: str, text2: str) -> str:
            n, m = len(text1), len(text2)
    
            # 1) Build DP table (lengths)
            dp = [[0] * (m + 1) for _ in range(n + 1)]
            for i in range(1, n + 1):
                for j in range(1, m + 1):
                    if text1[i - 1] == text2[j - 1]:
                        dp[i][j] = 1 + dp[i - 1][j - 1]
                    else:
                        dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])
    
            # 2) Backtrack from bottom-right to build one LCS
            i, j = n, m
            lcs_chars = []
            while i > 0 and j > 0:
                if text1[i - 1] == text2[j - 1]:
                    lcs_chars.append(text1[i - 1])  # pick the char
                    i -= 1
                    j -= 1
                else:
                    # Move in the direction of the larger value
                    if dp[i - 1][j] >= dp[i][j - 1]:
                        i -= 1
                    else:
                        j -= 1
    
            # 3) Reverse and join to get the LCS string
            return ''.join(reversed(lcs_chars))

    Code explanation

    • The dp table stores LCS lengths for all prefix pairs. The extra row and column at index 0 handle empty prefixes and simplify boundaries.
    • After filling dp, the algorithm starts from (n, m) and reconstructs a valid LCS by:
      • Taking matched characters and moving diagonally when text1[i-1] == text2[j-1].
      • Otherwise stepping toward the neighbor cell that preserved the larger LCS value during the build phase.
    • Collected characters are in reverse, so the final step reverses them to produce the correct order.

    Time and Space Complexity

    • Precise
      • Building the table visits each cell once: O(n · m) time
      • Backtracking touches at most n + m cells: O(n + m) time
      • Total time: O(n · m + n + m) which simplifies to O(n · m)
      • Space for the table: O(n · m)
    • Simplified
      • O(n · m) time and O(n · m) space

    If only the length is required, space can be optimized to O(min(n, m)). For printing the actual string using this exact backtrack approach, the full table is convenient and standard.


    Conclusion

    To print an LCS, first compute the DP length table, then backtrack from the bottom right to collect one valid subsequence. This method is deterministic, easy to implement, and runs in O(n · m) time. It is the canonical solution when you need the actual subsequence rather than just its length.

    Join our Advance DSA COURSE

    For any changes to the article, kindly email at code@codeanddebug.in or contact us at +91-9712928220.

    Dynamic Programming on Strings Hard
    Share. Facebook Twitter Pinterest LinkedIn Tumblr Email
    Previous ArticleLongest Common Subsequence | Leetcode 1143 | All DP Approach
    Next Article Longest Common Substring | Solved using Tabulation
    Anirudh Khurana
    • Website

    Anirudh Khurana is the founder of Code and Debug, an Indian EdTech platform that helps students and working professionals crack coding interviews and move into data and AI roles. He teaches DSA, Python, SQL, data engineering and machine learning through live bootcamps and his YouTube channel, Code and Debug, which has over 50,000 subscribers. Every guide on this blog is written or reviewed by him and tested with real code.

    Related Posts

    Data Structures & Algorithms

    DSA Interview Cheat Sheet: All Patterns You Need to Know

    4 April 2026
    Data Structures & Algorithms

    Symmetric Tree | Leetcode 101 | Recursive DFS Approach

    2 September 2025
    Data Structures & Algorithms

    Binary Tree Right Side View | Leetcode 199 | BFS and DFS Approaches

    2 September 2025
    Add A Comment
    Leave A Reply Cancel Reply

    Categories
    • AI & Machine Learning (4)
    • Data Structures & Algorithms (241)
      • Beginner (82)
      • Expert (52)
      • Intermediate (106)
    • Pandas (1)
    • Python (1)
    • Resume (1)
    • SQL (1)
    Recent Posts

    Confusion Matrix in Machine Learning: An Interactive Guide

    21 October 2026

    100 SQL Interview Questions with Queries and Answers (Freshers to Experienced)

    17 October 2026

    Logistic Regression in Machine Learning: Explained Visually (with Python)

    17 October 2026

    Linear Regression in Machine Learning: Explained Visually (with Python)

    17 October 2026

    100 Python Interview Questions and Answers for Freshers and Experienced (Free PDF)

    17 October 2026
    Facebook Instagram YouTube LinkedIn WhatsApp
    © 2025 Code and Debug. All rights reserved.

    Type above and press Enter to search. Press Esc to cancel.