【问题标题】:Why I'm getting TLE even if I'm using memoization? [closed]为什么即使我正在使用记忆,我也会得到 TLE? [关闭]
【发布时间】:2021-02-07 04:36:44
【问题描述】:

这是问题陈述

给定两个字符串 s1 和 s2,返回它们的最长公共子序列的长度。

字符串的子序列是从原始字符串生成的新字符串,其中删除了一些字符(可以是无),而不改变剩余字符的相对顺序。 (例如,“ace”是“abcde”的子序列,而“aec”不是)。两个字符串的公共子序列是两个字符串共有的子序列。

如果没有公共子序列,则返回0。

这是我的代码

class Solution {
public:
    int dp[1001][1001];
    int lcs(string s1,string s2,int n,int m){
        if (n==0 || m == 0)
            return 0;
        if(dp[n][m]!=-1)
            return dp[n][m];
        if (s1[n-1] == s2[m-1])
        {
            return dp[n][m]=  1 + lcs(s1,s2,n-1,m-1);
        }
        else
        {
            return dp[n][m]= max(lcs(s1,s2,n-1,m), lcs(s1,s2,n,m-1));
        }
        return dp[n][m];
    }
    int longestCommonSubsequence(string s1, string s2) {
        memset(dp,-1,1001*1001*sizeof(int));
        return lcs(s1,s2, s1.size(), s2.size());
        
    }
};

谢谢

【问题讨论】:

  • 所有字符串都需要传值吗?
  • 顺便说一句,你确定这是正确的算法吗?当传递"abcde""ba"时,函数返回2。按问题语句不应该是1吗?
  • 我认为 TLE 是指超出时间限制,但世界不会从 TLA 的无休止扩散中获得无限收益。
  • return dp[n][m]; 永远不会在lcs 函数结束时执行。
  • @Bob__ 它不是最长的公共子字符串,请参阅en.wikipedia.org/wiki/Longest_common_subsequence_problem

标签: c++ recursion memoization cp


【解决方案1】:

您的实现至少有 2 项可以进一步改进。

  • 您正在使用递归算法,请将其重写为迭代版本
  • 您使用的是 1001*1001 数组,因此您在某种程度上破坏了缓存

有一个更节省空间的算法,Hirschberg's algorithm,只返回 LCS 的长度。

【讨论】:

    【解决方案2】:

    在函数定义中使用引用调用而不是值调用。

    int lcs(string &s1,string &s2,int n,int m);
    
    int longestCommonSubsequence(string &s1, string &s2);
    

    【讨论】:

      猜你喜欢
      • 2021-01-14
      • 2016-01-24
      • 2018-10-21
      • 2015-10-24
      • 2014-08-10
      • 1970-01-01
      • 2019-09-27
      • 2012-08-31
      • 1970-01-01
      相关资源
      最近更新 更多