From 628f184af5c58d3c2a6d5a94e7ff1911fedcecb9 Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Fri, 7 Apr 2017 03:19:02 +0100 Subject: [PATCH 1/3] The program returns now the longest increasing subsequence instead of returning only the length. Code optimized and well commented --- .../longest_increasing_subsequence.py | 46 ++++++++++++++----- 1 file changed, 35 insertions(+), 11 deletions(-) diff --git a/dynamic_programming/longest_increasing_subsequence.py b/dynamic_programming/longest_increasing_subsequence.py index 37ddef207..59d8e2bf9 100644 --- a/dynamic_programming/longest_increasing_subsequence.py +++ b/dynamic_programming/longest_increasing_subsequence.py @@ -1,12 +1,36 @@ -""" -The Longest Increasing Subsequence (LIS) problem is to find the length of the longest subsequence of a given sequence such that all elements of the subsequence are sorted in increasing order. For example, the length of LIS for {10, 22, 9, 33, 21, 50, 41, 60, 80} is 6 -""" -def LIS(arr): - n= len(arr) - lis = [1]*n +''' +Author : Mehdi ALAOUI - for i in range(1, n): - for j in range(0, i): - if arr[i] > arr[j] and lis[i] <= lis[j]: - lis[i] = lis[j] + 1 - return max(lis) +This is a pure Python implementation of Dynamic Programming solution to the longest increasing subsequence of a given sequence. + +The problem is : +Given an ARRAY, to find the longest and increasing sub ARRAY in that given ARRAY and return it. +Example: [10, 22, 9, 33, 21, 50, 41, 60, 80] as input will return [10, 22, 33, 41, 60, 80] as output +''' + +def longestSub(ARRAY): #This function is recursive + + ARRAY_LENGTH = len(ARRAY) + if(ARRAY_LENGTH <= 1): #If the array contains only one element, we return it (it's the stop condition of recursion) + return ARRAY + #Else + PIVOT=ARRAY[0] + LONGEST_SUB=[] #This array will contains the longest increasing sub array + for i in range(1,ARRAY_LENGTH): + if (ARRAY[i] < PIVOT): #For each element from the array (except the pivot), if the element is smaller than the pivot, it won't figure on the sub array that contains the pivot + TEMPORARY_ARRAY = [ element for element in ARRAY[i:] if element >= ARRAY[i] ] #But it cas figure in an increasing sub array starting from this element + TEMPORARY_ARRAY = longestSub(TEMPORARY_ARRAY) #We calculate the longest sub array that starts from this element + if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): #And we save the longest sub array that begins from an element smaller than the pivot (in LONGEST_SUB) + LONGEST_SUB = TEMPORARY_ARRAY + + TEMPORARY_ARRAY = [ element for element in ARRAY[1:] if element >= PIVOT ] #Then we delete these elements (smaller than the pivot) from the initial array + TEMPORARY_ARRAY = [PIVOT] + longestSub(TEMPORARY_ARRAY) #And we calculate the longest sub array containing the pivot (in TEMPORARY_ARRAY) + if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): #Then we compare the longest array between TEMPORARY_ARRAY and LONGEST_SUB + return TEMPORARY_ARRAY + else: #And we return the longest one + return LONGEST_SUB + +#Some examples + +print(longestSub([4,8,7,5,1,12,2,3,9])) +print(longestSub([9,8,7,6,5,7])) \ No newline at end of file From e01cf425bd7ea081b7593cb5d423a2233e89dfff Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Fri, 7 Apr 2017 03:27:15 +0100 Subject: [PATCH 2/3] Comments reviewed --- dynamic_programming/longest_increasing_subsequence.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dynamic_programming/longest_increasing_subsequence.py b/dynamic_programming/longest_increasing_subsequence.py index 59d8e2bf9..e3f0a668b 100644 --- a/dynamic_programming/longest_increasing_subsequence.py +++ b/dynamic_programming/longest_increasing_subsequence.py @@ -16,8 +16,8 @@ def longestSub(ARRAY): #This function is recursive #Else PIVOT=ARRAY[0] LONGEST_SUB=[] #This array will contains the longest increasing sub array - for i in range(1,ARRAY_LENGTH): - if (ARRAY[i] < PIVOT): #For each element from the array (except the pivot), if the element is smaller than the pivot, it won't figure on the sub array that contains the pivot + for i in range(1,ARRAY_LENGTH): #For each element from the array (except the pivot), + if (ARRAY[i] < PIVOT): #if the element is smaller than the pivot, it won't figure on the sub array that contains the pivot TEMPORARY_ARRAY = [ element for element in ARRAY[i:] if element >= ARRAY[i] ] #But it cas figure in an increasing sub array starting from this element TEMPORARY_ARRAY = longestSub(TEMPORARY_ARRAY) #We calculate the longest sub array that starts from this element if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): #And we save the longest sub array that begins from an element smaller than the pivot (in LONGEST_SUB) From 08cbd113a4a4aa87ee1bc278ff19791806763492 Mon Sep 17 00:00:00 2001 From: Mehdi ALAOUI Date: Mon, 10 Apr 2017 13:49:01 +0100 Subject: [PATCH 3/3] Code optimized and complexity decreased --- .../longest_increasing_subsequence.py | 25 +++++++++++-------- 1 file changed, 15 insertions(+), 10 deletions(-) diff --git a/dynamic_programming/longest_increasing_subsequence.py b/dynamic_programming/longest_increasing_subsequence.py index e3f0a668b..c04f6673f 100644 --- a/dynamic_programming/longest_increasing_subsequence.py +++ b/dynamic_programming/longest_increasing_subsequence.py @@ -15,19 +15,24 @@ def longestSub(ARRAY): #This function is recursive return ARRAY #Else PIVOT=ARRAY[0] - LONGEST_SUB=[] #This array will contains the longest increasing sub array - for i in range(1,ARRAY_LENGTH): #For each element from the array (except the pivot), - if (ARRAY[i] < PIVOT): #if the element is smaller than the pivot, it won't figure on the sub array that contains the pivot - TEMPORARY_ARRAY = [ element for element in ARRAY[i:] if element >= ARRAY[i] ] #But it cas figure in an increasing sub array starting from this element - TEMPORARY_ARRAY = longestSub(TEMPORARY_ARRAY) #We calculate the longest sub array that starts from this element - if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): #And we save the longest sub array that begins from an element smaller than the pivot (in LONGEST_SUB) + isFound=False + i=1 + LONGEST_SUB=[] + while(not isFound and i= ARRAY[i] ] + TEMPORARY_ARRAY = longestSub(TEMPORARY_ARRAY) + if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): LONGEST_SUB = TEMPORARY_ARRAY + else: + i+=1 - TEMPORARY_ARRAY = [ element for element in ARRAY[1:] if element >= PIVOT ] #Then we delete these elements (smaller than the pivot) from the initial array - TEMPORARY_ARRAY = [PIVOT] + longestSub(TEMPORARY_ARRAY) #And we calculate the longest sub array containing the pivot (in TEMPORARY_ARRAY) - if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): #Then we compare the longest array between TEMPORARY_ARRAY and LONGEST_SUB + TEMPORARY_ARRAY = [ element for element in ARRAY[1:] if element >= PIVOT ] + TEMPORARY_ARRAY = [PIVOT] + longestSub(TEMPORARY_ARRAY) + if ( len(TEMPORARY_ARRAY) > len(LONGEST_SUB) ): return TEMPORARY_ARRAY - else: #And we return the longest one + else: return LONGEST_SUB #Some examples