如何打印实际的最长增长子序列,而不仅仅是长度

时间:2016-11-22 01:44:09

标签: python algorithm python-2.7 dynamic-programming

我正在审查Longest Increasing Subsequence的GeeksforGeeks代码,我试图弄清楚如何打印实际最长的增长子序列,而不仅仅是长度。

我知道我需要存储最大值的索引,然后打印出该数组中的实际数字......我只是在实现它时遇到了麻烦。

G4G网站的代码如下:

# Dynamic programming Python implementation of LIS problem

# lis returns length of the longest increasing subsequence
# in arr of size n
def lis(arr):
    n = len(arr)

    # Declare the list (array) for LIS and initialize LIS
    # values for all indexes
    lis = [1]*n

    # Compute optimized LIS values in bottom up manner
    for i in range (1 , n):
        for j in range(0 , i):
            if arr[i] > arr[j] and lis[i]< lis[j] + 1 :
                lis[i] = lis[j]+1

    # Initialize maximum to 0 to get the maximum of all
    # LIS
    maximum = 0

    # Pick maximum of all LIS values
    for i in range(n):
        maximum = max(maximum , lis[i])

    return maximum
# end of lis function

# Driver program to test above function
arr = [10, 22, 9, 33, 21, 50, 41, 60]
print "Length of lis is", lis(arr)
# This code is contributed by Nikhil Kumar Singh

1 个答案:

答案 0 :(得分:1)

正如您所指出的,LIS的索引也需要存储。

这可以通过引入一个额外的数组prev来完成。在原始代码中,lis(n)表示以n结尾的LIS的长度,我们有prev(n)表示LIS结束时n之前的索引号n 1}}(即LIS的倒数第二个索引号),如果以n结尾的LIS长度为1,我们只需定义prev(n) = n

每当您更新lis(n)的值时,prev(n)也需要相应更新。请在下面找到增强代码供您参考:

# Dynamic programming Python implementation of LIS problem

# lis returns length of the longest increasing subsequence
# in arr of size n
def lis(arr):
    n = len(arr)

    # Declare the list (array) for LIS and initialize LIS
    # values for all indexes
    lis = [1]*n

    prev = [0]*n
    for i in range(0, n):
        prev[i] = i

    # Compute optimized LIS values in bottom up manner
    for i in range (1 , n):
        for j in range(0 , i):
            if arr[i] > arr[j] and lis[i]< lis[j] + 1:
                lis[i] = lis[j]+1
                prev[i] = j

    # Initialize maximum to 0 to get the maximum of all
    # LIS
    maximum = 0
    idx = 0

    # Pick maximum of all LIS values
    for i in range(n):
        if maximum < lis[i]:
            maximum = lis[i]
            idx = i

    seq = [arr[idx]]
    while idx != prev[idx]:
        idx = prev[idx]
        seq.append(arr[idx])

    return (maximum, reversed(seq))
# end of lis function

# Driver program to test above function
arr = [10, 22, 9, 33, 21, 50, 41, 60]
ans = lis(arr)
print "Length of lis is", ans[0]
print "The longest sequence is", ", ".join(str(x) for x in ans[1])