1
+ /**
2
+ *
3
+ * Problem: Given a string of "n" characters, find the longest palindromic subsequence
4
+ * of the input string. The subsequnce can remove one or more elements from the original
5
+ * string retaining the original order of the string. This is a very different problem
6
+ * from finding the longest palindromic substring without the constraint of removing any
7
+ * elements.
8
+ *
9
+ * Use the brute force to generate all possible subsequences. While in a subsequence,
10
+ * if the string is already a palindrome from the ends, continue proceeding inwards.
11
+ * If it is not palindrome from the end, we can continue ignoring one elements from
12
+ * the left and right to see if we can achieve a palindromic subsequence. while the brute
13
+ * force exploration happens, we need to cache all the pre-computed results in an
14
+ * additional DP storage for use.
15
+ *
16
+ * Complexity....
17
+ * Time: O(n^2) since beg * end is the worst case of computation, rest of the computations
18
+ * are cached. Space: O(n^2 + n) since in the worst case, we would have all the n^2 positions
19
+ * cahced and stored. Additionally, O(n) space would be used for the recursion stack.
20
+ *
21
+ * @param input
22
+ */
23
+ function findLongestPalSubseq1 ( input : string ) {
24
+ return findLongestPalSubseqHelper1 ( input , 0 , input . length - 1 ) ;
25
+ }
26
+
27
+ function findLongestPalSubseqHelper1 ( input : string , beg : number , end : number , dp : number [ ] [ ] = [ ] ) : number {
28
+
29
+ dp [ beg ] = dp [ beg ] || [ ] ;
30
+
31
+ if ( dp [ beg ] [ end ] !== undefined )
32
+ return dp [ beg ] [ end ] ;
33
+
34
+ if ( end < beg ) return 0 ;
35
+ else if ( end === beg ) return 1 ;
36
+ else if ( input [ beg ] === input [ end ] ) {
37
+ // Ends are matching, continue inwards.
38
+ dp [ beg ] [ end ] = 2 + findLongestPalSubseqHelper1 ( input , beg + 1 , end - 1 ) ;
39
+ return dp [ beg ] [ end ]
40
+ }
41
+
42
+ // If the ends are not matching, we may try to skip an element from the end, to attempt
43
+ // to make a palindromic string
44
+ const maxWithLeftInclusion = findLongestPalSubseqHelper1 ( input , beg + 1 , end ) ;
45
+ const maxWithRightInclusion = findLongestPalSubseqHelper1 ( input , beg , end - 1 ) ;
46
+ dp [ beg ] [ end ] = Math . max ( maxWithLeftInclusion , maxWithRightInclusion ) ;
47
+ return dp [ beg ] [ end ] ;
48
+ }
49
+
50
+ function testLongestPlalindSubseq1 ( input : string ) {
51
+ console . log ( `Longest Palindromic Subsequence for input ${ input } : ${ findLongestPalSubseq1 ( input ) } ` )
52
+ }
53
+
54
+ testLongestPlalindSubseq1 ( "abdbca" )
55
+ testLongestPlalindSubseq1 ( "cddpd" )
56
+ testLongestPlalindSubseq1 ( "pqr" )
0 commit comments