Given a sequence, find the length of longest palindromic subsequence (LPS).
In Palindromic subsequence, elements read the same backword and forward.
A subsequence is a sequence that can be derived from anothe subsequence by deleting some or no elements without changing the order of remaining elements.
======= Examples: =======
Input: "abdbca"
Output: 5 => "abdba"
Input: "cddpd"
Output: 3 => "ddd"
Input: "pqr"
Output: 1 => any single char "p" or "q" or "r"
Code:
def find_lps_length_recursion(string):
start, end = 0, len(string) - 1
return find_lps_length_recursion_util(string, start, end)
def find_lps_length_recursion_util(string, start, end):
if (start > end):
return 0
if (start == end):
return 1
if (string[start] == string[end]):
return 2 + find_lps_length_recursion_util(string, start + 1, end - 1)
else:
skip_start_lps = find_lps_length_recursion_util(string, start + 1, end)
skip_end_lps = find_lps_length_recursion_util(string, start, end - 1)
return max(skip_start_lps, skip_end_lps)
print("Recursive Method :")
print(find_lps_length_recursion("abdbca"))
print(find_lps_length_recursion("cddpd"))
print(find_lps_length_recursion("pqr"))
Output:
Recursive Method :
5
3
1
Complexity:
Code:
def find_lps_length_dp_memoization(string):
n = len(string)
start, end = 0, n - 1
memory = [[None]*n for i in range(n)]
return find_lps_length_memoization_util(string, start, end, memory)
def find_lps_length_memoization_util(string, start, end, memory):
if (start > end):
return 0
if (start == end):
return 1
if (memory[start][end]):
return memory[start][end]
if (string[start] == string[end]):
memory[start][end] = 2 + find_lps_length_memoization_util(string, start + 1, end - 1, memory)
return memory[start][end]
skip_start_lps = find_lps_length_memoization_util(string, start + 1, end, memory)
skip_end_lps = find_lps_length_memoization_util(string, start, end - 1, memory)
memory[start][end] = max(skip_start_lps, skip_end_lps)
return memory[start][end]
print("\nDP -> Recursion + Memoization Method :")
print(find_lps_length_dp_memoization("abdbca"))
print(find_lps_length_dp_memoization("cddpd"))
print(find_lps_length_dp_memoization("pqr"))
Output:
DP -> Recursion + Memoization Method :
5
3
1
Complexity:
Table Filling Formula:
if string[start] == string[end]:
table[start][end] = 2 + table[start+1][end-1]
else:
table[start][end] = max(table[start+1][end], table[start][end-1])
Tabulation:
Final Table:
Code:
def find_lps_length_dp_tabulation(string):
n = len(string)
table = [[0] * n for _ in range(n)]
# When start and end indexes are equal palindrome length will be 1
for i in range(n):
table[i][i] = 1
# for filling table[start][end], we need to have table[start+1][end-1] ready
# Also, we need to fill only top right part of table coz bottom left will always be zero (start < end)
# Diaognal values will be 1, filled earlier
for start in range(n - 2, -1, -1):
for end in range(start + 1, n):
if (string[start] == string[end]):
table[start][end] = 2 + table[start + 1][end - 1]
else:
table[start][end] = max(table[start + 1][end], table[start][end - 1])
return table[0][n-1]
print("\nDP -> Iteration + Tabulation Method :")
print(find_lps_length_dp_tabulation("abdbca"))
print(find_lps_length_dp_tabulation("cddpd"))
print(find_lps_length_dp_tabulation("pqr"))
Output:
DP -> Iteration + Tabulation Method :
5
3
1
Complexity:
Given a string, find the length of its longest palindromic substring.
A substring is a continuous part of string and palindromic substring, elements read the same backword and forward.
======= Examples: =======
Input: "abdbca"
Output: 3 => "bdb"
Input: "cddpd"
Output: 3 => "dpd"
Input: "pqr"
Output: 1 => any single char "p" or "q" or "r"
Code:
def find_lps_length_recursion(string):
start, end = 0, len(string) - 1
return find_lps_length_recursion_util(string, start, end)
def find_lps_length_recursion_util(string, start, end):
if (start > end):
return 0
if (start == end):
return 1
if (string[start] == string[end]):
remainingLength = end - start - 1
if (remainingLength == find_lps_length_recursion_util(string, start + 1, end - 1)):
return 2 + remainingLength
skip_start_lps = find_lps_length_recursion_util(string, start + 1, end)
skip_end_lps = find_lps_length_recursion_util(string, start, end - 1)
return max(skip_start_lps, skip_end_lps)
print("Recursive Method :")
print(find_lps_length_recursion("abdbca"))
print(find_lps_length_recursion("cddpd"))
print(find_lps_length_recursion("pqr"))
Output:
Recursive Method :
3
3
1
Complexity:
Code:
def find_lps_length_dp_memoization(string):
n = len(string)
start, end = 0, n - 1
memory = [[None]*n for _ in range(n)]
return find_lps_length_dp_memoization_util(string, start, end, memory)
def find_lps_length_dp_memoization_util(string, start, end, memory):
if (start > end):
return 0
if (start == end):
return 1
if (memory[start][end]):
return memory[start][end]
if (string[start] == string[end]):
remainingLength = end - start - 1
if (remainingLength == find_lps_length_dp_memoization_util(string, start + 1, end - 1, memory)):
memory[start][end] = 2 + remainingLength
return memory[start][end]
skip_start_lps = find_lps_length_dp_memoization_util(string, start + 1, end, memory)
skip_end_lps = find_lps_length_dp_memoization_util(string, start, end - 1, memory)
memory[start][end] = max(skip_start_lps, skip_end_lps)
return memory[start][end]
print("\nDP -> Recursion + Memoization Method :")
print(find_lps_length_dp_memoization("abdbca"))
print(find_lps_length_dp_memoization("cddpd"))
print(find_lps_length_dp_memoization("pqr"))
Output:
DP -> Recursion + Memoization Method :
3
3
1
Complexity:
Table Filling Formula:
if(string[start] == string[end]):
if( remaining string is of zero length or remaing string is a palindrome i.e. table[start+1][end-1] == True):
table[start][end] = True
Tabulation:
Final Table:
Code:
def find_lps_length_dp_tabulation(string):
n = len(string)
table = [[False] * n for _ in range(n)]
# Substring of length-1 will always be palindrome
for i in range(n):
table[i][i] = True
lps_length = 1
for start in range(n - 2, -1, -1):
for end in range(start + 1, n):
# If char at start and index is same
if (string[start] == string[end]):
# If remaining string is of zero length or it is a palindrome
if (end - start == 1 or table[start + 1][end - 1]):
table[start][end] = True
lps_length = max(lps_length, end - start + 1)
return lps_length
print("\nDP -> Iteration + Tabulation Method :")
print(find_lps_length_dp_tabulation("abdbca"))
print(find_lps_length_dp_tabulation("cddpd"))
print(find_lps_length_dp_tabulation("pqr"))
Output:
DP -> Iteration + Tabulation Method :
3
3
1
Complexity:
← Previous: Unbounded Knapsack Pattern
Next: Longest Common Substring Pattern →