问题描述
为什么我的用于查找Longest Common Subsequence
的c ++实现在LeetCode上给出了time limit error
。如何改善该算法的时间复杂度?
int longestCommonSubsequence(string text1,string text2) {
int n1 = text1.length(),n2 = text2.length();
vector<vector<int>> dp(n1+1,vector<int>(n2+1,-1));
longestCommonSubsequence(text1,text2,n1,n2,dp);
return dp[n1][n2];
}
int longestCommonSubsequence(string text1,string text2,int n1,int n2,vector<vector<int>> &dp) {
if(n1==0 || n2==0) {
return 0;
}
if(dp[n1][n2] != -1) {
return dp[n1][n2];
}
if(text1[n1-1]==text2[n2-1]) {
dp[n1][n2] = 1 + longestCommonSubsequence(text1,n1-1,n2-1,dp);
return dp[n1][n2];
}
else {
dp[n1][n2] = max(longestCommonSubsequence(text1,dp),longestCommonSubsequence(text1,dp));
return dp[n1][n2];
}
}
解决方法
与动态编程类似,我们可以不递归地解决问题。没有TLE的情况会通过:
// The following block might slightly improve the execution time;
// Can be removed;
static const auto __optimize__ = []() {
std::ios::sync_with_stdio(false);
std::cin.tie(nullptr);
std::cout.tie(nullptr);
return 0;
}();
// Most of headers are already included;
// Can be removed;
#include <cstdint>
#include <string>
#include <vector>
#include <algorithm>
using ValueType = std::uint_fast16_t;
static const struct Solution {
static const int longestCommonSubsequence(
const std::string& text_a,const std::string& text_b
) {
const ValueType a_len = std::size(text_a);
const ValueType b_len = std::size(text_b);
std::vector<std::vector<ValueType>> dp(a_len + 1,std::vector<ValueType>(b_len + 1));
for (ValueType a = 1; a <= a_len; ++a) {
for (ValueType b = 1; b <= b_len; ++b) {
if (text_a[a - 1] == text_b[b - 1]) {
dp[a][b] = 1 + dp[a - 1][b - 1];
} else {
dp[a][b] = std::max(dp[a - 1][b],dp[a][b - 1]);
}
}
}
return dp[a_len][b_len];
}
};
,
发送 text1 和 text2 作为引用,因为如果我们按值传递它,对于每次递归调用,都会创建一个字符串的副本,这对于每次递归调用来说都是额外的 O(string_length) 开销。