• day-54 代码随想录算法训练营(19) 动态规划 part 15


    392.判断子序列

    思路一:双指针进行遍历判断
    1. class Solution {
    2. public:
    3. bool isSubsequence(string s, string t) {
    4. if(s.size()>t.size()) return false;
    5. int s_ptr=0,t_ptr=0;
    6. while(t_ptrsize()){
    7. if(s[s_ptr]==t[t_ptr]) s_ptr++;
    8. t_ptr++;
    9. }
    10. if(s_ptr==s.size()) return true;
    11. return false;
    12. }
    13. };
    思路二:动态规划
    • 1.dp存储:以t[i-1]结尾,s[j-1]结尾的两个字符串最长子序列为dp[i][j]
    • 2.动态转移方程:
    •               if(t[i-1]==s[j-1]) dp[i][j]=dp[i-1][j-1]+1; 
    •               else dp[i][j]=dp[i-1][j];
    • 3.初始化:全为1
    • 4.1~n
    1. class Solution {
    2. public:
    3. bool isSubsequence(string s, string t) {
    4. int n=t.size(),m=s.size();
    5. vectorint>>dp(n+1,vector<int>(m+1,0));
    6. for(int i=1;i<=n;i++){
    7. for(int j=1;j<=m;j++){
    8. if(t[i-1]==s[j-1]) dp[i][j]=dp[i-1][j-1]+1;
    9. else dp[i][j]=dp[i-1][j];//看和s比较,t中的最长相同子序列
    10. }
    11. }
    12. return dp[n][m]==m ;
    13. }
    14. };

    115.不同的子序列

    思路:
    • 1.dp存储:以s[i-1]结尾的字符串可以组成以t[j-1]结尾的字符串 dp[i][j]个
    • 2.动态转移方程:
    •               if(s[i-1]==t[j-1]) 使用s[i-1] 和不使用 s[i-1]
    •               else dp[i][j]=dp[i-1][j];
    • 3.初始化:dp[i][0]一定为1,因为t不取;dp[0][j]一定为0,因为s不取;dp[0][0]为1
    • 4.遍历顺序: 1~n
    1. class Solution {
    2. public:
    3. int numDistinct(string s, string t) {
    4. int n=s.size(),m=t.size();
    5. vectoruint64_t>>dp(n+1,vector<uint64_t>(m+1,0));
    6. for(int i=0;i0]=1;
    7. for(int i=1;i<=n;i++){
    8. for(int j=1;j<=m;j++){
    9. if(s[i-1]==t[j-1]) dp[i][j]=dp[i-1][j-1]+dp[i-1][j];
    10. else dp[i][j]=dp[i-1][j];
    11. }
    12. }
    13. return dp[n][m];
    14. }
    15. };

    583.两个字符串的删除操作

    思路:
    • 1.dp存储:以word1[i-1]结尾,word2[j-1]结尾的两个字符串相同的最小操作数
    • 2.动态转移方程:
    •               if(word1[i-1]==word2[j-1]) dp[i][j]=dp[i-1][j-1]
    •               else dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1)
    • 3.初始化:dp[i][0]=i   dp[0][j]=j
    • 4.遍历顺序:1~n
    1. class Solution {
    2. public:
    3. int minDistance(string word1, string word2) {
    4. int n=word1.size(),m=word2.size();
    5. vectorint>>dp(n+1,vector<int>(m+1,0));
    6. for(int i=0;i<=n;i++) dp[i][0]=i;//word2长度为0时,word1需要全部删除
    7. for(int j=0;j<=m;j++) dp[0][j]=j;
    8. for(int i=1;i<=n;i++){
    9. for(int j=1;j<=m;j++){
    10. if(word1[i-1]==word2[j-1]) dp[i][j]=dp[i-1][j-1];//相等时,当前位置不考虑
    11. else dp[i][j]=min(dp[i-1][j]+1,dp[i][j-1]+1);//不等时,考虑哪边进行减少
    12. }
    13. }
    14. return dp[n][m];
    15. }
    16. };

  • 相关阅读:
    【JVM技术专题】针对于Java类加载器系统研究指南 「入门篇」
    数学建模资料分享
    ​探秘 Web 水印技术
    【1.1】神经网络:关于神经网络的介绍
    算法学习笔记-LeetCode215-数组中的第K个最大元素
    K-优字符串(冬季每日一题 11)
    智能井盖传感器:城市安全卫士
    OA产品选型的指导原则
    【攻破css系列——第九天】常规流
    c++以exception_ptr传递异常
  • 原文地址:https://blog.csdn.net/Ricardo_XIAOHAO/article/details/132963758