Search code examples
pythondynamic-programming

Obtaining the longest increasing subsequence in Python


Can anyone tell me why this code doesn't produce each increasing subsequence? I used dynamic programming to solve this but I can't figure out why this code fails. The parameter A is a sequence of integers.

def LIS(A):

    # make a list of lists
    L = list()
    for i in range(0, len(A)):
        L.append(list())

    #the first increasing subsequence is the first element in A
    L[0].append(A[0])

    for i in range(1, len(A)):
        for j in (0, i):

            # a new larger increasing subsequence found
            if (A[j] < A[i]) and ( len(L[i]) < len(L[j]) ):
                L[i] = L[j]

        L[i].append(A[i])

        # print an increasing subsequence
        print L[i]

Example output produced for A = [3, 5, 10, 0, 1, 100, 2, 4, 7] by this algorithm:

[3, 5]
[3, 5, 10]
[0]
[1]
[3, 5, 10, 100]
[2]
[3, 5, 10, 100, 4]
[3, 5, 10, 100, 4, 7]
None

Correct output:

[3] 
[3, 5] 
[3, 5, 10] 
[0] 
[0, 1] 
[3, 5, 10, 100] 
[0, 1, 2] 
[0, 1, 2, 4] 
[0, 1, 2, 4, 7] 

Solution

  • Two mistakes that I found in your code

    1.You assumed list are immutable but they are not in python

    L[i] = L[j] this is going to make L[i] point to the same list pointed by L[j]
    
    2.for j in (0, i):
    

    This does not iterate j form 0 to i-1 it iterates j form 0 to i.

    Here is fixed version of your code.

    def LIS(A):
    
        # make a list of lists
        L = list()
        for i in range(0, len(A)):
            L.append(list())
    
        # the first increasing subsequence is the first element in A
        L[0].append(A[0])
    
        for i in range(1, len(A)):
            for j in range(0, i):
    
                # a new larger increasing subsequence found
                if (A[j] < A[i]) and (len(L[i]) < len(L[j])):
                    'throw the previous list'
                    L[i] = []
                    'add all elements of L[j] to L[i]'
                    L[i].extend(L[j])
            L[i].append(A[i])
    
        for i in range(len(A)):
        # print an increasing subsequence
            print (L[i])
    A = [3, 5, 10, 0, 1, 100, 2, 4, 7]
    LIS(A)