|
1 | 1 | package com.thealgorithms.dynamicprogramming; |
2 | 2 |
|
3 | 3 | /** |
4 | | - * Algorithm explanation |
5 | | - * https://www.educative.io/edpresso/longest-palindromic-subsequence-algorithm |
| 4 | + * Longest Palindromic Subsequence algorithm. |
| 5 | + * A palindromic subsequence is a subsequence that reads the same forwards and backwards. |
| 6 | + * This implementation finds the longest such subsequence by computing the LCS of the |
| 7 | + * original string and its reverse. |
| 8 | + * |
| 9 | + * @see <a href="https://en.wikipedia.org/wiki/Longest_palindromic_subsequence">Wikipedia</a> |
6 | 10 | */ |
7 | 11 | public final class LongestPalindromicSubsequence { |
8 | 12 | private LongestPalindromicSubsequence() { |
9 | 13 | } |
10 | 14 |
|
11 | | - public static void main(String[] args) { |
12 | | - String a = "BBABCBCAB"; |
13 | | - String b = "BABCBAB"; |
14 | | - |
15 | | - String aLPS = lps(a); |
16 | | - String bLPS = lps(b); |
17 | | - |
18 | | - System.out.println(a + " => " + aLPS); |
19 | | - System.out.println(b + " => " + bLPS); |
20 | | - } |
21 | | - |
22 | | - public static String lps(String original) throws IllegalArgumentException { |
23 | | - StringBuilder reverse = new StringBuilder(original); |
24 | | - reverse = reverse.reverse(); |
25 | | - return recursiveLPS(original, reverse.toString()); |
| 15 | + /** |
| 16 | + * Returns the longest palindromic subsequence of the given string. |
| 17 | + * |
| 18 | + * @param original the input string |
| 19 | + * @return the longest palindromic subsequence |
| 20 | + * @throws IllegalArgumentException if the input string is null |
| 21 | + */ |
| 22 | + public static String lps(String original) { |
| 23 | + if (original == null) { |
| 24 | + throw new IllegalArgumentException("Input string must not be null"); |
| 25 | + } |
| 26 | + String reverse = new StringBuilder(original).reverse().toString(); |
| 27 | + return recursiveLPS(original, reverse); |
26 | 28 | } |
27 | 29 |
|
28 | 30 | private static String recursiveLPS(String original, String reverse) { |
29 | | - String bestResult = ""; |
30 | | - |
31 | | - // no more chars, then return empty |
32 | | - if (original.length() == 0 || reverse.length() == 0) { |
33 | | - bestResult = ""; |
34 | | - } else { |
35 | | - // if the last chars match, then remove it from both strings and recur |
36 | | - if (original.charAt(original.length() - 1) == reverse.charAt(reverse.length() - 1)) { |
37 | | - String bestSubResult = recursiveLPS(original.substring(0, original.length() - 1), reverse.substring(0, reverse.length() - 1)); |
38 | | - |
39 | | - bestResult = reverse.charAt(reverse.length() - 1) + bestSubResult; |
40 | | - } else { |
41 | | - // otherwise (1) ignore the last character of reverse, and recur on original and |
42 | | - // updated reverse again (2) ignore the last character of original and recur on the |
43 | | - // updated original and reverse again then select the best result from these two |
44 | | - // subproblems. |
45 | | - |
46 | | - String bestSubResult1 = recursiveLPS(original, reverse.substring(0, reverse.length() - 1)); |
47 | | - String bestSubResult2 = recursiveLPS(original.substring(0, original.length() - 1), reverse); |
48 | | - if (bestSubResult1.length() > bestSubResult2.length()) { |
49 | | - bestResult = bestSubResult1; |
50 | | - } else { |
51 | | - bestResult = bestSubResult2; |
52 | | - } |
53 | | - } |
| 31 | + if (original.isEmpty() || reverse.isEmpty()) { |
| 32 | + return ""; |
54 | 33 | } |
55 | | - |
56 | | - return bestResult; |
| 34 | + if (original.charAt(original.length() - 1) == reverse.charAt(reverse.length() - 1)) { |
| 35 | + String bestSubResult = recursiveLPS(original.substring(0, original.length() - 1), reverse.substring(0, reverse.length() - 1)); |
| 36 | + return reverse.charAt(reverse.length() - 1) + bestSubResult; |
| 37 | + } |
| 38 | + String sub1 = recursiveLPS(original, reverse.substring(0, reverse.length() - 1)); |
| 39 | + String sub2 = recursiveLPS(original.substring(0, original.length() - 1), reverse); |
| 40 | + return sub1.length() >= sub2.length() ? sub1 : sub2; |
57 | 41 | } |
58 | 42 | } |
0 commit comments