Skip to main content
  1. LeetCode/

LeetCode 1143: Longest Common Subsequence

·3 mins· ·
LeetCode Medium Dynamic-Programming String
Wei Yi Chung
Author
Wei Yi Chung
Working at the contributing of open source, distributed systems, and data engineering.
Table of Contents

Meta Data
#

Difficulty: medium First Attempt: 2026-07-11 Source: Day 36 learning note

Study Context
#

This article is rebuilt from the exact LeetCode section in the learning note. I kept the note’s repair points, comparison points, and common mistakes, while removing unrelated non-LeetCode material from the same day.

Related Reminders From The Note#

  • LC 1143: pass after mismatch-proof wording repair
  • explain LC 1143 with exact prefix-based state and mismatch transition

Learning Note Extract
#

Problem 1 - LC 1143 Longest Common Subsequence
#

  • Pattern: 2D DP on two prefixes.

Why This Fits
#

At any pair of positions, the question is:

what is the LCS length for the prefixes up to these two positions?

That naturally gives a 2D table over:

  • prefix of text1
  • prefix of text2

Core State / Invariant
#

dp[i][j] = length of the longest common subsequence between text1[:i] and text2[:j]

Base Case
#

If either prefix is empty:

dp[i][0] = 0
dp[0][j] = 0

Reason:

an empty string has no common subsequence with positive length

Transition
#

If the new characters match:

text1[i - 1] == text2[j - 1]
=> dp[i][j] = dp[i - 1][j - 1] + 1

If they do not match:

dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

Why This Works
#

  • match:
    • the matching characters can extend the best subsequence from the smaller prefixes
  • mismatch:
    • one of the two last characters is not used, so drop one side and keep the better answer

Complexity
#

Time: O(m * n)
Space: O(m * n)

Can be compressed to:

Space: O(n)

Common Mistakes
#

  • using substring instead of subsequence reasoning
  • mixing character index with prefix length index
  • forgetting that mismatch takes max(up, left)
  • saying diagonal is used on every step

Strong Spoken Explanation
#

I define dp[i][j] as the LCS length between the prefixes text1[:i] and text2[:j]. The base row and base column are zero because an empty prefix cannot contribute any positive common subsequence. If the current characters match, I extend the smaller-prefix answer from the diagonal by one. If they do not match, I drop one side and keep the better result from up or left. The final answer is dp[m][n].

Clean Solution
#

The note above captures the reasoning and the mistakes to avoid. The implementation below is the version I would submit.

class Solution:
    def longestCommonSubsequence(self, text1: str, text2: str) -> int:
        m, n = len(text1), len(text2)
        dp = [[0] * (n + 1) for _ in range(m + 1)]

        for i in range(1, m + 1):
            for j in range(1, n + 1):
                if text1[i - 1] == text2[j - 1]:
                    dp[i][j] = dp[i - 1][j - 1] + 1
                else:
                    dp[i][j] = max(dp[i - 1][j], dp[i][j - 1])

        return dp[m][n]

Complexity
#

Time O(mn), Space O(mn), compressible to O(n).

Mistakes To Watch
#

  • Using substring logic; subsequence does not require contiguous characters.
  • On mismatch, incorrectly taking diagonal.

Final Interview Explanation
#

Start from the state definition, then explain why the transition preserves that state. If there is a loop direction, state compression, or a similar-looking problem with a different answer shape, call that out explicitly because that is where this problem family usually breaks down.

Related

LeetCode 516: Longest Palindromic Subsequence
·3 mins
LeetCode Medium Dynamic-Programming String Palindrome
LeetCode note for Longest Palindromic Subsequence, rebuilt from the original learning note
LeetCode 139: Word Break
·2 mins
LeetCode Medium Dynamic-Programming String
LeetCode note for Word Break, rebuilt from the original learning note
LeetCode 91: Decode Ways
·3 mins
LeetCode Medium Dynamic-Programming String
LeetCode note for Decode Ways, rebuilt from the original learning note
LeetCode 931: Minimum Falling Path Sum
·3 mins
LeetCode Medium Dynamic-Programming Grid-Dp
LeetCode note for Minimum Falling Path Sum, rebuilt from the original learning note
LeetCode 576: Out of Boundary Paths
·3 mins
LeetCode Medium Dynamic-Programming Grid-Dp
LeetCode note for Out of Boundary Paths, rebuilt from the original learning note
LeetCode 1277: Count Square Submatrices With All Ones
·3 mins
LeetCode Medium Dynamic-Programming Grid-Dp
LeetCode note for Count Square Submatrices With All Ones, rebuilt from the original learning note