718. 最长重复子数组

== 连续のLCS
给两个整数数组 AB ,返回两个数组中公共的、长度最长的子数组的长度。
输入:
A: [1,2,3,2,1]
B: [3,2,1,4,7]
输出:3
解释:
长度最长的公共子数组是 [3, 2, 1] 。

  1. //动态规划法,二维时空都是O(nm),通法
  2. func findLength(nums1 []int, nums2 []int) int {
  3. m, n := len(nums1), len(nums2)
  4. dp := make([][]int, m+1)
  5. res := 0 //多的一句,用于判断连续
  6. for i := range dp { //注意range遍历= i 从0~m 左闭右开,取i+1; 或者1~m,左闭右闭
  7. dp[i] = make([]int, n+1)
  8. }
  9. for i := 1; i <= m; i++ {
  10. for j := 1; j <= n; j++ {
  11. if nums1[i-1] == nums2[j-1] {
  12. dp[i][j] = dp[i-1][j-1] +1
  13. } else {
  14. dp[i][j] = 0 //其实 没意义的,因为也不会选它,只是更完整
  15. }
  16. res = max(res, dp[i][j])
  17. }
  18. }
  19. return res //返回连续的数组个数
  20. }
  21. func max(x,y int) int {
  22. if x > y {
  23. return x
  24. }
  25. return y
  26. }
//注意滚动数组会发生覆盖,要从后往前遍历
//滚动数组, 一维空间降为O(min(m,n))
func findLength(nums1 []int, nums2 []int) int {
    m, n := len(nums1), len(nums2)
    dp := make([]int, n+1)
    res := 0                            //多的一句,用于判断连续

    for i := 1; i <= m; i++ {      
        pre := 0                                   //引入临时数组,滚动      

        for j := 1; j <= n; j++ {
            temp := dp[j]                         // 1,tmp 记录的是二维dp矩阵正上方的值

            if nums1[i-1] == nums2[j-1] {
                dp[j] = pre + 1                 // 2,pre 记录的是二维dp矩阵左上方的值     
            } else {
                dp[j] = 0                       //这个else 蛮难理解?
            }
            res = max(res, dp[j])
            pre = temp                             // 3,右边顺序记录
        }
    }
    return res
}

func max(x,y int) int {
    if x > y {
        return x
    }
    return y
}