Given a string s
, find the length of the longest palindromic subsequence 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.
For example:
Input: s = "bbbab" Output: 4 Explanation: One possible longest palindromic subsequence is "bbbb".
Input: s = "cbbd" Output: 2 Explanation: One possible longest palindromic subsequence is "bb".
Write a function to efficiently find the length of the longest palindromic subsequence. What is the time and space complexity of your solution? Can you identify and address potential edge cases? Explain your approach clearly. Begin with a naive approach if that helps structure your thoughts.
Given a string s
, the task is to find the length of the longest palindromic subsequence 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: Input: s = "bbbab" Output: 4 Explanation: One possible longest palindromic subsequence is "bbbb".
A brute-force approach would involve generating all possible subsequences of the given string and checking each subsequence to see if it is a palindrome. We would then keep track of the longest palindromic subsequence found so far.
This approach is highly inefficient because the number of subsequences for a string of length n
is 2^n. For each subsequence, checking if it's a palindrome takes O(n) time. Therefore, the overall time complexity would be O(n * 2^n).
A more efficient approach uses dynamic programming. We can define dp[i][j]
as the length of the longest palindromic subsequence of the substring s[i...j]
. Then we have the following recurrence relation:
s[i] == s[j]
, then dp[i][j] = dp[i+1][j-1] + 2
s[i] != s[j]
, then dp[i][j] = max(dp[i+1][j], dp[i][j-1])
Base case:
dp[i][i] = 1
for all i
The length of the longest palindromic subsequence of the entire string s
will be dp[0][n-1]
, where n
is the length of s
.
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 len = 2; len <= n; len++) {
for (int i = 0; i <= n - len; i++) {
int j = i + len - 1;
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];
}
}
s
because we have two nested loops.dp
table of size n x n.