Longest Palindromic Subsequence
MEDIUMDescription
Given a string s, find the longest palindromic subsequence's length in s.
A subsequence is a sequence that can be derived from another sequence by deleting some or no elements without changing the order of the remaining elements.
Example 1:
Input: s = "bbbab" Output: 4 Explanation: One possible longest palindromic subsequence is "bbbb".
Example 2:
Input: s = "cbbd" Output: 2 Explanation: One possible longest palindromic subsequence is "bb".
Constraints:
1 <= s.length <= 1000sconsists only of lowercase English letters.
Approaches
Checkout 3 different approaches to solve Longest Palindromic Subsequence. Click on different approaches to view the approach and algorithm in detail.
Brute Force Recursion
This approach solves the problem by breaking it down into smaller, overlapping subproblems using recursion. We define a function that calculates the length of the longest palindromic subsequence for a given substring. The solution explores all possibilities without storing intermediate results, leading to exponential time complexity.
Algorithm
- Define a recursive function
solve(s, i, j)that computes the length of the longest palindromic subsequence in the substrings[i...j]. - Base Cases:
- If
i > j(empty substring), return 0. - If
i == j(single character), return 1.
- If
- Recursive Step:
- If
s.charAt(i) == s.charAt(j), the characters at the ends match. They contribute 2 to the length. The rest of the palindrome is found in the inner substring. Return2 + solve(s, i + 1, j - 1). - If
s.charAt(i) != s.charAt(j), the end characters don't match. We must discard one of them. We find the maximum length by either excluding the start character (solve(s, i + 1, j)) or the end character (solve(s, i, j - 1)). Returnmax(solve(s, i + 1, j), solve(s, i, j - 1)).
- If
- The initial call is
solve(s, 0, s.length() - 1).
We define a recursive function, say solve(s, i, j), which computes the length of the longest palindromic subsequence in the substring s[i...j]. The logic is as follows:
-
Base Cases:
- If the start index
iis greater than the end indexj, it means we have an empty substring, so we return 0. - If
iequalsj, we have a single-character substring, which is always a palindrome of length 1.
- If the start index
-
Recursive Step:
- If the characters at the ends of the substring,
s[i]ands[j], are the same, they can form the ends of a palindrome. The length will be 2 plus the length of the LPS in the inner substrings[i+1...j-1]. So, we return2 + solve(s, i + 1, j - 1). - If the characters
s[i]ands[j]are different, we cannot include both in the same palindrome. We have two choices:- Exclude
s[i]and find the LPS ins[i+1...j]. - Exclude
s[j]and find the LPS ins[i...j-1]. We take the maximum of these two possibilities:max(solve(s, i + 1, j), solve(s, i, j - 1)).
- Exclude
- If the characters at the ends of the substring,
The initial call to find the answer for the whole string s would be solve(s, 0, s.length() - 1). This method recomputes the same subproblems multiple times, making it highly inefficient.
class Solution {
public int longestPalindromeSubseq(String s) {
return solve(s, 0, s.length() - 1);
}
private int solve(String s, int i, int j) {
// Base case 1: Empty substring
if (i > j) {
return 0;
}
// Base case 2: Single character substring
if (i == j) {
return 1;
}
// If characters at both ends match
if (s.charAt(i) == s.charAt(j)) {
return 2 + solve(s, i + 1, j - 1);
} else {
// If characters do not match
return Math.max(solve(s, i + 1, j), solve(s, i, j - 1));
}
}
}
Complexity Analysis
Pros and Cons
- Simple to understand and implement.
- Directly follows the problem's recursive definition.
- Extremely inefficient due to a large number of redundant computations for the same subproblems.
- Will result in a 'Time Limit Exceeded' (TLE) error on most platforms for non-trivial input sizes.
Code Solutions
Checking out 3 solutions in different languages for Longest Palindromic Subsequence. Click on different languages to view the code.
class Solution { public int longestPalindromeSubseq ( String s ) { int n = s . length (); int [][] dp = new int [ n ][ n ]; for ( int i = 0 ; i < n ; ++ i ) { dp [ i ][ i ] = 1 ; } for ( int j = 1 ; j < n ; ++ j ) { for ( int i = j - 1 ; i >= 0 ; -- i ) { if ( s . charAt ( i ) == s . charAt ( j )) { dp [ i ][ j ] = dp [ i + 1 ][ j - 1 ] + 2 ; } else { dp [ i ][ j ] = Math . max ( dp [ i + 1 ][ j ], dp [ i ][ j - 1 ]); } } } return dp [ 0 ][ n - 1 ]; } }Video Solution
Watch the video walkthrough for Longest Palindromic Subsequence
Similar Questions
5 related questions you might find useful
Patterns:
Data Structures:
Companies:
Subscribe to Scale Engineer newsletter
Learn about System Design, Software Engineering, and interview experiences every week.
No spam, unsubscribe at any time.