栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > C/C++/C#

【golang必备算法】动态规划 子数组与子序列问题

C/C++/C# 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

【golang必备算法】动态规划 子数组与子序列问题

动态规划 子数组与子序列问题

动态规划经典题目,718. 最长重复子数组 、1143. 最长公共子序列 。 两个字符串求最长重复子数组和最长子序列

两道题不同之处在于 子数组要求连续,而子序列不一定都是连续的,只要前面有相同的子序列,哪怕当前比较的字符不一样,那么当前字符串之前的子序列也不会为 0。而子串(子数组)是连续的,若当前比较的字符不相同,则当前位置的最长公共子数组(子串)的长度为 0,即 dp[i][j] = 0(就是没有)。

所以DP里不同之处在于两点:

  • dp的定义。1143题定义dp[i][j]为截止到nums1[:i-1]和nums2[:j-1]的最长公共子序列的长度。718题dp的定义是nums1[:i-1]和nums2[:j-1]的最大"公共后缀""子数组长度。718题dp的定义保证了所求得的dp值反映了连续的子数组匹配,即nums1[:i-1]和nums2[:j-1]的末尾部分是匹配的。

  • 状态的转移。1143题找的截止到nums1[:i-1]和nums2[:j-1]的最长公共子序列的长度,所以即便是尾部不相等,都要考虑截止到nums1[:i - 2]和nums2[:j-1],和截止到nums1[:i-1]和nums2[:j - 2]的状态(取dp[i - 1][j]和dp[i][j - 1]的较大值)。但718题中,如果尾部不相等,表明没有公共后缀(从后向前看),所以dp[i][j] = 0。

故718题 如果nums1[i - 1] != nums2[j - 1],则dp[i][j] = 0,因为必须要以第i和第j个元素结尾


1143. 最长公共子序列
func longestCommonSubsequence(text1 string, text2 string) int {
    //dp[i][j]代表长度为[0, i - 1]的字符串text1与长度为[0, j - 1]的字符串text2的最长公共子序列为dp[i][j]
    dp := make([][]int,len(text1)+1)
    for i:=0;i<=len(text1);i++{
        dp[i] = make([]int,len(text2)+1)
    }

    for i:=1;i<=len(text1);i++{
        for j:=1;j<=len(text2);j++{
            if text1[i-1] == text2[j-1]{
                dp[i][j] = dp[i-1][j-1] + 1
            }else{
                dp[i][j] = max(dp[i-1][j],dp[i][j-1])
            }
        }
    }
return dp[len(text1)][len(text2)]

}

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

718. 最长重复子数组
func findLength(nums1 []int, nums2 []int) int {
    //因为dp[i][j] 和 dp[i-1][j-1]有关,当i=0或j=0时,dp[-1][-1]无意义,所以dp[0][j]、dp[i][0]、dp[0][0]要手动初始化,太过麻烦
  //故以dp[i][j] 代表以nums[i-1]和 nums[j-1]为结尾的最长子数组的长度。
  //也就是最大"公共后缀"子数组长度,注意这里一定要是以i-1和j-1为结尾的
  // 如果nums1[i - 1] != nums2[j - 1],则dp[i][j] = 0,因为必须要以第i和第j个元素结尾

  dp := make([][]int,len(nums1)+1)  //长度多增加1
  for i:=0;i
      dp[i] = make([]int,len(nums2)+1)
  }
  
    res := 0
    //从dp定义可知要从 1 开始遍历
  for i:=1;i
      for j:=1;j
          if nums1[i-1] == nums2[j-1]{
              dp[i][j] = dp[i-1][j-1] + 1
          }
          if dp[i][j] > res{
              res = dp[i][j]
          }
      }
  }
  return res  
}
转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/949800.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号