带记忆化递归的C++最长回文子序列解法超时,Python版却通过
为什么C++版最长回文子序列递归代码超时,而Python版可以通过?
核心原因在于两个版本代码的字符串传递方式以及细节实现的差异,具体分析如下:
1. 字符串传递的开销差异
C++版本的lps函数中,参数string s是按值传递的:
int lps(string s, int i, int j){
每次递归调用都会完整拷贝整个字符串,对于长度接近1000的输入字符串来说,每次拷贝都会产生大量的内存操作和时间消耗,递归深度最多可达1000层,累积的拷贝开销直接导致了超时。
而Python版本中,字符串是不可变对象,函数参数传递的是引用:
def lps(self, s, i, j, dp):
递归时不会复制整个字符串,这部分的开销几乎可以忽略,这是Python代码能通过的关键因素之一。
2. DP数组的初始化细节
C++版本将dp设为类成员变量,在构造函数中固定初始化1001x1001的数组:
Solution(){ dp = vector<vector<int>>(1001, vector<int>(1001, -1)); }
虽然这个大小能覆盖题目最大输入长度(1000),但相比Python中每次调用longestPalindromeSubseq时才创建刚好匹配输入长度的dp数组:
dp = [[-1 for x in range(len(s))] for y in range(len(s))]
C++的固定大小数组可能会带来轻微的缓存命中率差异,不过这不是导致超时的主要原因。
3. 递归调用的实际开销抵消
通常C++的递归调用开销比Python小,但字符串拷贝的巨大开销完全抵消了这一优势,甚至导致整体性能劣于Python版本。
修复C++代码的建议
将字符串参数改为const引用传递,避免递归时的拷贝:
int lps(const string& s, int i, int j){
修改后,C++版本的性能会大幅提升,即可通过所有测试用例。
内容的提问来源于stack exchange,提问作者Rkedio
相关产品推荐
相关产品推荐

