diff --git a/dynamic_programming/longest_increasing_subsequence.py b/dynamic_programming/longest_increasing_subsequence.py index d827893763c5..629799d4a46b 100644 --- a/dynamic_programming/longest_increasing_subsequence.py +++ b/dynamic_programming/longest_increasing_subsequence.py @@ -1,5 +1,6 @@ """ Author : Mehdi ALAOUI +Optimized : Arunkumar This is a pure Python implementation of Dynamic Programming solution to the longest increasing subsequence of a given sequence. @@ -13,46 +14,54 @@ from __future__ import annotations -def longest_subsequence(array: list[int]) -> list[int]: # This function is recursive +def longest_subsequence(array: list[int]) -> list[int]: """ - Some examples + Find the longest increasing subsequence in the given array + using dynamic programming. + + Args: + array (list[int]): The input array. + + Returns: + list[int]: The longest increasing subsequence. + + Examples: >>> longest_subsequence([10, 22, 9, 33, 21, 50, 41, 60, 80]) [10, 22, 33, 41, 60, 80] >>> longest_subsequence([4, 8, 7, 5, 1, 12, 2, 3, 9]) [1, 2, 3, 9] >>> longest_subsequence([9, 8, 7, 6, 5, 7]) - [8] + [5, 7] >>> longest_subsequence([1, 1, 1]) - [1, 1, 1] + [1] >>> longest_subsequence([]) [] """ - array_length = len(array) - # If the array contains only one element, we return it (it's the stop condition of - # recursion) - if array_length <= 1: - return array - # Else - pivot = array[0] - is_found = False - i = 1 - longest_subseq: list[int] = [] - while not is_found and i < array_length: - if array[i] < pivot: - is_found = True - temp_array = [element for element in array[i:] if element >= array[i]] - temp_array = longest_subsequence(temp_array) - if len(temp_array) > len(longest_subseq): - longest_subseq = temp_array - else: - i += 1 - - temp_array = [element for element in array[1:] if element >= pivot] - temp_array = [pivot, *longest_subsequence(temp_array)] - if len(temp_array) > len(longest_subseq): - return temp_array - else: - return longest_subseq + if not array: + return [] + + n = len(array) + # Initialize an array to store the length of the longest + # increasing subsequence ending at each position. + lis_lengths = [1] * n + + for i in range(1, n): + for j in range(i): + if array[i] > array[j]: + lis_lengths[i] = max(lis_lengths[i], lis_lengths[j] + 1) + + # Find the maximum length of the increasing subsequence. + max_length = max(lis_lengths) + + # Reconstruct the longest subsequence in reverse order. + subsequence = [] + current_length = max_length + for i in range(n - 1, -1, -1): + if lis_lengths[i] == current_length: + subsequence.append(array[i]) + current_length -= 1 + + return subsequence[::-1] # Reverse the subsequence to get the correct order. if __name__ == "__main__":