These are related problems but not exactly, Longest Common Subsequence (LCS) can be used on strings or integers (or any comparable object) - Longest Increasing Subsequence is basically just for real numbers , who have an order - if you used the ascii value of letters or some other mapping to numbers, it would work just as well. LIS has it’s application in graph theory, finding the longest path of a directed acyclic graph. One of the applications for LCS is matching sequences in the human genome.
Now, on with the code! The first bit of code I didn’t write - it’s a mash up of code from my python algorithms book and a python activestate recipe . I am including it just to compare the two. The second code listing is entirely my own.
With dynamic programming (memoization), the complexity will be O(m x n) where m and n are the input strings.
def memo(f): cache = {} def wraps(*args): if args not in cache: cache[args] = f(*args) return cache[args] return wraps @memo def LCS(str1, str2): if len(str1)==0 or len(str2)==0: return '' if str1[-1] == str2[-1]: return LCS(str1[:-1], str2[:-1]) + str1[-1] else: candidate1 = LCS(str1[:-1], str2) candidate2 = LCS(str1, str2[:-1]) if len(candidate1) >= len(candidate2): return candidate1 else: return candidate2
For example:
>>> LCS("BERTIE", "SIMOWN") "I" >>> LCS("GRAHAM", "GRANBY") "GRA" >>> LCS("SHECKY", "SHECKY") "SHECKY"
Next, is the Longest Increasing Subsequence:
def LIS(seq): maxSeq = [] s = [seq[0]] for i in range (1, len(seq)): if seq[i-1] < seq[i]: s.append(seq[i]) else: if len(s) > len(maxSeq): maxSeq = s s = [] return maxSeq
The algorithm checks if the previous member of the sequence is less than it and adds it to s. If the value is larger, it checks to see if s is larger than the maximum sequence stored. s is then cleared and the algorithm resumes from 1 after the current LIS. Example:
>>> a = [5, 6, 2, 11, 13, 90, 4, 3, 17, 19, 2, 3, 6]The algorithm only checks if a subsequence is bigger than the one stored, therefore it will only return the first largest increasing subsequence.b = [1, 2, 1, 3, 4, 9, 7, 2] LIS(a) [11, 13, 90] LIS(b) [3, 4, 9]