How to determine the longest increasing subsequence using dynamic programming?

前端 未结 19 2592
醉梦人生
醉梦人生 2020-11-22 10:55

I have a set of integers. I want to find the longest increasing subsequence of that set using dynamic programming.

19条回答
  •  慢半拍i
    慢半拍i (楼主)
    2020-11-22 11:18

    Speaking about DP solution, I found it surprising that no one mentioned the fact that LIS can be reduced to LCS. All you need to do is sort the copy of the original sequence, remove all the duplicates and do LCS of them. In pseudocode it is:

    def LIS(S):
        T = sort(S)
        T = removeDuplicates(T)
        return LCS(S, T)
    

    And the full implementation written in Go. You do not need to maintain the whole n^2 DP matrix if you do not need to reconstruct the solution.

    func lcs(arr1 []int) int {
        arr2 := make([]int, len(arr1))
        for i, v := range arr1 {
            arr2[i] = v
        }
        sort.Ints(arr1)
        arr3 := []int{}
        prev := arr1[0] - 1
        for _, v := range arr1 {
            if v != prev {
                prev = v
                arr3 = append(arr3, v)
            }
        }
    
        n1, n2 := len(arr1), len(arr3)
    
        M := make([][]int, n2 + 1)
        e := make([]int, (n1 + 1) * (n2 + 1))
        for i := range M {
            M[i] = e[i * (n1 + 1):(i + 1) * (n1 + 1)]
        }
    
        for i := 1; i <= n2; i++ {
            for j := 1; j <= n1; j++ {
                if arr2[j - 1] == arr3[i - 1] {
                    M[i][j] = M[i - 1][j - 1] + 1
                } else if M[i - 1][j] > M[i][j - 1] {
                    M[i][j] = M[i - 1][j]
                } else {
                    M[i][j] = M[i][j - 1]
                }
            }
        }
    
        return M[n2][n1]
    }
    

提交回复
热议问题