From 2e859bc4b56b24e84077b43e21b8e1deb4da6743 Mon Sep 17 00:00:00 2001 From: The-Kid-Gid Date: Wed, 25 Nov 2020 19:11:22 -0500 Subject: [PATCH 1/3] Add greedy method for longest palindromic subsequence --- .../greedy_longest_palindromic_subsequence.py | 58 +++++++++++++++++++ 1 file changed, 58 insertions(+) create mode 100644 greedy_method/greedy_longest_palindromic_subsequence.py diff --git a/greedy_method/greedy_longest_palindromic_subsequence.py b/greedy_method/greedy_longest_palindromic_subsequence.py new file mode 100644 index 000000000000..399e03a77e7f --- /dev/null +++ b/greedy_method/greedy_longest_palindromic_subsequence.py @@ -0,0 +1,58 @@ +""" +The longest palindromic subsequence (LPS) is the longest +subsequence in a string that is the same when reversed. +A subsequence is not the same as a substring. +Unlike substrings, the characters of subsequences are not required +to occupy consecutive positions. + +Explanation: +https://www.techiedelight.com/longest-palindromic-subsequence-using-dynamic-programming/ +""" + + +def longest_palindromic_subsequence(sequence: str, i: int, j: int) -> int: + """Find the longest palindromic subsequence in a given string + + :param sequence: The sequence to search in + :type sequence: str + :param i: The initial lower index bounding the search area + :type i: int + :param j: The initial upper index bounding the search area + :type j: int + :return: The length of the longest palindromic subsequence + :rtype: int + + >>> longest_palindromic_subsequence("ABBDCACB", 0, 7) + 5 + >>> longest_palindromic_subsequence("nurses run", 0, 9) + 9 + >>> longest_palindromic_subsequence("Z", 0, 0) + 1 + """ + # If the sequence only has one character, it is a palindrome + # This prevents a one-letter palindrome from being counted as 2 + if i == j: + return 1 + + # Base case: If i is greater than j you have gone too far + if i > j: + return 0 + + # If the first character of the current string equals the last + if sequence[i] == sequence[j]: + # Recur with the remaining substring + return longest_palindromic_subsequence(sequence, i + 1, j - 1) + 2 + + # If the first and last characters are NOT equal, then find the larger LPS between: + # a.) the substring formed by removing the first character + # b.) the substring formed by removing the last character + return max( + longest_palindromic_subsequence(sequence, i + 1, j), + longest_palindromic_subsequence(sequence, i, j - 1), + ) + + +if __name__ == "__main__": + sequence = input("Enter sequence string: ") + len_lps = longest_palindromic_subsequence(sequence, 0, len(sequence) - 1) + print(f'The length of the LPS in "{sequence}" is {len_lps}') From 3eaed00fb26aa5496b32b9263ebeca1bcdd8d4a8 Mon Sep 17 00:00:00 2001 From: The-Kid-Gid Date: Wed, 25 Nov 2020 19:28:25 -0500 Subject: [PATCH 2/3] Fix non-descriptive names --- .../greedy_longest_palindromic_subsequence.py | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/greedy_method/greedy_longest_palindromic_subsequence.py b/greedy_method/greedy_longest_palindromic_subsequence.py index 399e03a77e7f..8a57c2ee96fc 100644 --- a/greedy_method/greedy_longest_palindromic_subsequence.py +++ b/greedy_method/greedy_longest_palindromic_subsequence.py @@ -10,7 +10,7 @@ """ -def longest_palindromic_subsequence(sequence: str, i: int, j: int) -> int: +def longest_palindromic_subsequence(sequence: str, begin_substring: int, end_substring: int) -> int: """Find the longest palindromic subsequence in a given string :param sequence: The sequence to search in @@ -31,24 +31,24 @@ def longest_palindromic_subsequence(sequence: str, i: int, j: int) -> int: """ # If the sequence only has one character, it is a palindrome # This prevents a one-letter palindrome from being counted as 2 - if i == j: + if begin_substring == end_substring: return 1 # Base case: If i is greater than j you have gone too far - if i > j: + if begin_substring > end_substring: return 0 # If the first character of the current string equals the last - if sequence[i] == sequence[j]: + if sequence[begin_substring] == sequence[end_substring]: # Recur with the remaining substring - return longest_palindromic_subsequence(sequence, i + 1, j - 1) + 2 + return longest_palindromic_subsequence(sequence, begin_substring + 1, end_substring - 1) + 2 # If the first and last characters are NOT equal, then find the larger LPS between: # a.) the substring formed by removing the first character # b.) the substring formed by removing the last character return max( - longest_palindromic_subsequence(sequence, i + 1, j), - longest_palindromic_subsequence(sequence, i, j - 1), + longest_palindromic_subsequence(sequence, begin_substring + 1, end_substring), + longest_palindromic_subsequence(sequence, begin_substring, end_substring - 1), ) From 768db4f42a7ef7aba42f2200f33544b2576644c0 Mon Sep 17 00:00:00 2001 From: The-Kid-Gid Date: Wed, 25 Nov 2020 19:34:10 -0500 Subject: [PATCH 3/3] Fix formatting --- .../greedy_longest_palindromic_subsequence.py | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/greedy_method/greedy_longest_palindromic_subsequence.py b/greedy_method/greedy_longest_palindromic_subsequence.py index 8a57c2ee96fc..0767374a7ba9 100644 --- a/greedy_method/greedy_longest_palindromic_subsequence.py +++ b/greedy_method/greedy_longest_palindromic_subsequence.py @@ -10,7 +10,9 @@ """ -def longest_palindromic_subsequence(sequence: str, begin_substring: int, end_substring: int) -> int: +def longest_palindromic_subsequence( + sequence: str, begin_substring: int, end_substring: int +) -> int: """Find the longest palindromic subsequence in a given string :param sequence: The sequence to search in @@ -41,7 +43,12 @@ def longest_palindromic_subsequence(sequence: str, begin_substring: int, end_sub # If the first character of the current string equals the last if sequence[begin_substring] == sequence[end_substring]: # Recur with the remaining substring - return longest_palindromic_subsequence(sequence, begin_substring + 1, end_substring - 1) + 2 + return ( + longest_palindromic_subsequence( + sequence, begin_substring + 1, end_substring - 1 + ) + + 2 + ) # If the first and last characters are NOT equal, then find the larger LPS between: # a.) the substring formed by removing the first character