Skip to main content
  1. LeetCode/

LeetCode 516: Longest Palindromic Subsequence

·3 mins· ·
LeetCode Medium Dynamic-Programming String Palindrome
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 516 tests whether you can switch from prefix-style DP to interval-style DP cleanly.
  • LC 516: partial pass after teaching repair
  • explain LC 516 with exact interval-based state and fill order

Learning Note Extract
#

Problem 2 - LC 516 Longest Palindromic Subsequence
#

  • Pattern: interval DP on substrings.

Why This Fits
#

This is not a two-string prefix table.

The right question is:

what is the longest palindromic subsequence inside s[left:right+1]?

That naturally gives an interval DP.

Core State / Invariant
#

dp[left][right] = length of the longest palindromic subsequence inside s[left:right+1]

Base Cases
#

Single character:

dp[i][i] = 1

Reason:

one character is already a palindrome of length 1

Transition
#

If the two ends match:

s[left] == s[right]
=> dp[left][right] = dp[left + 1][right - 1] + 2

If they do not match:

dp[left][right] = max(dp[left + 1][right], dp[left][right - 1])

Fill Order
#

The interval depends on smaller inner intervals, so fill by:

  • increasing substring length or
  • left decreasing, right increasing

Complexity
#

Time: O(n^2)
Space: O(n^2)

Common Mistakes
#

  • confusing subsequence with substring
  • filling the table in the wrong order
  • forgetting dp[i][i] = 1
  • assuming matching ends always means the whole interval is a palindrome substring

Strong Spoken Explanation
#

I define dp[left][right] as the length of the longest palindromic subsequence inside that substring interval. A single character is length 1, so dp[i][i] = 1. If the two ends match, I can wrap the best inner answer with those two characters and add 2. If they do not match, one of the ends is not used in the optimal subsequence, so I take the better answer from dropping the left side or dropping the right side. The key implementation detail is fill order, because each state depends on smaller inner intervals.

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 longestPalindromeSubseq(self, s: str) -> int:
        n = len(s)
        dp = [[0] * n for _ in range(n)]

        for l in range(n - 1, -1, -1):
            dp[l][l] = 1
            for r in range(l + 1, n):
                if s[l] == s[r]:
                    dp[l][r] = 2 + dp[l + 1][r - 1]
                else:
                    dp[l][r] = max(dp[l + 1][r], dp[l][r - 1])

        return dp[0][n - 1] if n else 0

Complexity
#

Time O(n^2), Space O(n^2).

Mistakes To Watch
#

  • Using substring logic instead of subsequence logic.
  • Filling intervals in the wrong order.

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 1143: Longest Common Subsequence
·3 mins
LeetCode Medium Dynamic-Programming String
LeetCode note for Longest Common 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 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 63: Unique Paths II
·3 mins
LeetCode Medium Dynamic-Programming Grid-Dp
LeetCode note for Unique Paths II, 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