最长公共子序列(数组,动态规划)

GitHub:github.com/bllon/Data-structure-an...
题目:

最长公共子序列
求给定的两个数组的最长公共子序列长度
例如 arr1 = [1,2,4,6,9,13], arr2 = [1,3,4,6,9,15]
那么最长公共子序列长度为4, (1,4,6,9)

解法: 来自百度百科
动态规划的一个计算两个序列的最长公共子序列的方法如下: [1]
以两个序列 XY 为例子:
设有二维数组f[i,j] 表示 X 的 i 位和 Y 的 j 位之前的最长公共子序列的长度,则有:
f[1][1] = same(1,1);
f[i,j] = max{f[i-1][j -1] + same(i,j),f[i-1,j],f[i,j-1]};
其中,same(a,b)X 的第 a 位与 Y 的第 b 位相同时为“1”,否则为“0”。
此时,二维数组中最大的数便是 XY 的最长公共子序列的长度,依据该数组回溯,便可找出最长公共子序列。
该算法的空间、时间复杂度均为O(n^2),经过优化后,空间复杂度可为O(n)

代码:

package main

import "fmt"

func max(a, b int) int {
    if a > b {
        return a
    }
    return b
}

func same(a, b int) int {
    if a == b {
        return 1
    }
    return 0
}

func LCSL(arr1 []int, arr2 []int) int {
    len1, len2 := len(arr1), len(arr2)
    if len1 == 0 || len2 == 0 {
        return 0
    }

    //dp数组
    var dp [][]int //dp[i][j]代表arr1[i]和arr2[j]的位置之前最长公共子序列长度
    dp = make([][]int, len1+1)
    for i := 0; i <= len1; i++ {
        dp[i] = make([]int, len2+1)
    }

    for i := 1; i <= len1; i++ {
        for j := 1; j <= len2; j++ {
            if arr1[i-1] == arr2[j-1] {
                dp[i][j] = dp[i-1][j-1] + 1
            } else {
                dp[i][j] = max(dp[i][j-1], dp[i-1][j])
            }
        }
    }

    return dp[len1][len2]
}

func main() {
    fmt.Println(LCSL([]int{1, 2, 4, 6, 9, 13, 15}, []int{1, 3, 4, 6, 9, 15}))
    return
}

结果:

5
本作品采用《CC 协议》,转载必须注明作者和本文链接
GitHub地址:github.com/bllon
讨论数量: 0
(= ̄ω ̄=)··· 暂无内容!

讨论应以学习和精进为目的。请勿发布不友善或者负能量的内容,与人为善,比聪明更重要!