|
| 1 | +package algorithms.dynamic |
| 2 | + |
| 3 | +/// Compute the length of the longest palindromic subsequence for a given string. |
| 4 | +/// A subsequence is a sequence derived from the original string by deleting some or no characters |
| 5 | +/// without changing the order of the remaining characters. |
| 6 | +/// |
| 7 | +/// - dp(i)(j) represents the length of the longest palindromic subsequence in s(i..j). |
| 8 | +/// The recurrence relation is: |
| 9 | +/// - If s(i) == s(j) then: |
| 10 | +/// dp(i)(j) = dp(i+1)(j-1) + 2 |
| 11 | +/// (if the substring length is 2, then dp(i)(j) = 2) |
| 12 | +/// - Otherwise: |
| 13 | +/// dp(i)(j) = max(dp(i+1)(j), dp(i)(j-1)) |
| 14 | +/// Base case: |
| 15 | +/// - dp(i)(i) = 1 (each individual character is a palindrome of length 1) |
| 16 | +/// |
| 17 | +/// Time Complexity: O(n²) – Each cell of the DP table is computed once. |
| 18 | + |
| 19 | +def longestPalindromicSubsequence(s: String): (Int, Array[Array[Int]]) = { |
| 20 | + val n: Int = s.length |
| 21 | + // Initialize DP table with zeros. |
| 22 | + val dp: Array[Array[Int]] = Array.fill(n, n)(0) |
| 23 | + |
| 24 | + // Base Case: every single character is a palindrome of length 1. |
| 25 | + for (i <- 0 until n) { |
| 26 | + dp(i)(i) = 1 |
| 27 | + } |
| 28 | + |
| 29 | + // Build the DP table for substrings of length 2 to n. |
| 30 | + for (len <- 2 to n) { |
| 31 | + for (i <- 0 to n - len) { |
| 32 | + val j = i + len - 1 |
| 33 | + if (s(i) == s(j)) { |
| 34 | + dp(i)(j) = if (len == 2) 2 else dp(i + 1)(j - 1) + 2 |
| 35 | + } else { |
| 36 | + dp(i)(j) = Math.max(dp(i + 1)(j), dp(i)(j - 1)) |
| 37 | + } |
| 38 | + } |
| 39 | + } |
| 40 | + |
| 41 | + (dp(0)(n - 1), dp) |
| 42 | +} |
| 43 | + |
| 44 | +@main |
| 45 | +def mainLongestPalindromicSubsequence(): Unit = { |
| 46 | + val inputString: String = "character" |
| 47 | + val (lpsLength, dpMatrix) = longestPalindromicSubsequence(inputString) |
| 48 | + println(s"Longest Palindromic Subsequence length for '$inputString' is: $lpsLength") |
| 49 | + println("DP Matrix:") |
| 50 | + dpMatrix.foreach { row => |
| 51 | + println(row.mkString(" ")) |
| 52 | + } |
| 53 | +} |
0 commit comments