PracHub
QuestionsPremiumCoachesLearningGuidesInterview Prep

Quick Overview

This question evaluates understanding of dynamic programming for strings, specifically longest palindromic subsequence concepts such as memoization, bottom-up DP, space optimization and subsequence reconstruction.

  • Medium
  • J.P. Morgan
  • Coding & Algorithms
  • Software Engineer

Compute longest palindromic subsequence

Company: J.P. Morgan

Role: Software Engineer

Category: Coding & Algorithms

Difficulty: Medium

Interview Round: Onsite

Given a string s (1 ≤ |s| ≤ 2000), implement a function that returns the length of the longest subsequence of s that reads the same forward and backward. Provide both a top-down (memoized) and a bottom-up dynamic programming solution, analyze time and space complexity, and explain how to optimize space. Follow up: reconstruct one valid longest palindromic subsequence and discuss how to handle multiple test cases efficiently.

Quick Answer: This question evaluates understanding of dynamic programming for strings, specifically longest palindromic subsequence concepts such as memoization, bottom-up DP, space optimization and subsequence reconstruction.

Part 1: Compute the Length of the Longest Palindromic Subsequence

Given a string s, return the length of its longest palindromic subsequence. A subsequence is formed by deleting zero or more characters without changing the order of the remaining characters. The subsequence does not need to be contiguous.

Constraints

  • 0 <= len(s) <= 2000
  • Character comparisons are case-sensitive.

Examples

Input: "bbbab"

Expected Output: 4

Explanation: One longest palindromic subsequence is 'bbbb'.

Input: "cbbd"

Expected Output: 2

Explanation: The longest palindromic subsequence is 'bb'.

Input: "agbdba"

Expected Output: 5

Explanation: One longest palindromic subsequence is 'abdba'.

Input: "a"

Expected Output: 1

Explanation: A single character is always a palindrome of length 1.

Input: ""

Expected Output: 0

Explanation: The empty string has no subsequences, so the answer is 0.

Solution

def solution(s):
    if not s:
        return 0

    n = len(s)
    dp = [0] * n

    for i in range(n - 1, -1, -1):
        dp[i] = 1
        prev = 0
        for j in range(i + 1, n):
            temp = dp[j]
            if s[i] == s[j]:
                dp[j] = prev + 2
            else:
                dp[j] = max(dp[j], dp[j - 1])
            prev = temp

    return dp[-1]

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

Hints

  1. Try defining dp[i][j] as the answer for the substring from index i to j.
  2. If s[i] == s[j], those two characters can wrap a smaller palindromic subsequence. Otherwise, try skipping one end.

Part 2: Reconstruct One Longest Palindromic Subsequence

Given a string s, return one longest palindromic subsequence of s. If multiple longest palindromic subsequences exist, use this deterministic tie-break rule while reconstructing from the DP table: when skipping the left character and skipping the right character both keep the optimal length, skip the left character first. This makes the expected output unique.

Constraints

  • 0 <= len(s) <= 2000
  • The returned value must be both a palindrome and a subsequence of s.
  • Character comparisons are case-sensitive.

Examples

Input: "bbbab"

Expected Output: "bbbb"

Explanation: The reconstruction picks matching outer b characters and then another matching pair.

Input: "cbbd"

Expected Output: "bb"

Explanation: The longest palindromic subsequence is uniquely 'bb'.

Input: "agbdba"

Expected Output: "abdba"

Explanation: A full optimal reconstruction is 'abdba'.

Input: "abcda"

Expected Output: "ada"

Explanation: Several length-3 answers exist, and the required tie-break rule leads to 'ada'.

Input: ""

Expected Output: ""

Explanation: The empty string reconstructs to the empty palindrome.

Solution

def solution(s):
    if not s:
        return ''

    from array import array

    n = len(s)
    dp = [array('H', [0]) * n for _ in range(n)]

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

    left = []
    right = []
    i, j = 0, n - 1

    while i <= j:
        if i == j:
            left.append(s[i])
            break

        if s[i] == s[j] and dp[i][j] == dp[i + 1][j - 1] + 2:
            left.append(s[i])
            right.append(s[j])
            i += 1
            j -= 1
        elif dp[i + 1][j] >= dp[i][j - 1]:
            i += 1
        else:
            j -= 1

    return ''.join(left + right[::-1])

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

Hints

  1. First compute the LPS length for every substring, then walk inward from both ends to rebuild an answer.
  2. Build the result using a left half and a right half; when both skip choices are equally good, move the left pointer forward.
Last updated: May 6, 2026

Loading coding console...

PracHub

Master your tech interviews with 8,500+ real questions from top companies.

Product

  • Questions
  • Learning Tracks
  • Interview Guides
  • Resources
  • Premium
  • For Universities
  • Student Access

Browse

  • By Company
  • By Role
  • By Category
  • Topic Hubs
  • SQL Questions
  • Compare Platforms
  • Discord Community

Support

  • support@prachub.com
  • (916) 541-4762

Legal

  • Privacy Policy
  • Terms of Service
  • About Us

© 2026 PracHub. All rights reserved.

Related Coding Questions

  • Implement Integer Square Root - J.P. Morgan (medium)
  • Implement KNN from Scratch - J.P. Morgan (medium)
  • Minimize Operations to Balance Shipments - J.P. Morgan (medium)
  • Solve scheduling and collision problems - J.P. Morgan (medium)
  • Design an autocomplete suggestions API - J.P. Morgan (easy)