给你一个字符串 s,找到 s 中最长的 回文 子串。
示例 1:
1 2 3
| 输入:s = "babad" 输出:"bab" 解释:"aba" 同样是符合题意的答案。
|
示例 2:
思路:
先写一个判断字符串是不是回文的函数,比如
1 2 3 4
| int isPalindrome(string input){ return equal(input.begin(),input.begin()+ input.length()/2,input.rbegin()); }
|
然后开始遍历字符串,如果是就提取出回文字符串,之后如果再有就判断长度谁打谁小,遍历完后输出答案。
说起来容易写起来1还行,相对来说
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40
| class Solution { public: string longestPalindrome(string s) { if(s.empty()){ return ""; } int start = 0; int maxlen = 0; for(int i = 0 ; i< s.size(); ++i ){ int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i+1); int len3 = max(len1,len2);
if(len3 > maxlen){ start = i -(len3 - 1)/2; maxlen = max(maxlen,len3); }
} return s.substr(start,maxlen); }
private: int expandAroundCenter(string s, int left, int right){ int length = static_cast<int>(s.size()); while(right < length && left >= 0 && s[left] == s[right]){ --left; ++right;
} return right - left -1; };
};
|
附带一个deepseek的版本:
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42
| class Solution { public: string longestPalindrome(string s) { if (s.empty()) return ""; int start = 0; int maxLen = 1; for (int i = 0; i < s.length(); i++) { int len1 = expandAroundCenter(s, i, i); int len2 = expandAroundCenter(s, i, i + 1); int len = max(len1, len2); if (len > maxLen) { maxLen = len; start = i - (len - 1) / 2; } } return s.substr(start, maxLen); } private: int expandAroundCenter(const string& s, int left, int right) { while (left >= 0 && right < s.length() && s[left] == s[right]) { left--; right++; } return right - left - 1; } };
|

他的建议:
经过仔细对比,我发现有两个主要区别:
- 你的版本中,
expandAroundCenter函数的参数是string s,即按值传递字符串,这会拷贝整个字符串,导致性能下降。
而我的版本使用的是const string& s,即按引用传递,避免了拷贝。
- 另外,你的版本中在计算
maxlen时,虽然已经用len3和maxlen比较,但在更新时又调用了一次max(maxlen, len3),这是多余的,因为已经确定len3 > maxlen。
但是,最关键的性能差异应该是字符串的拷贝。当字符串很长时,每次调用expandAroundCenter都会复制整个字符串,这会导致巨大的开销。
另外,你的版本中maxlen初始化为0,而我的版本初始化为1。这个初始化值不会影响正确性,但可能会稍微影响一点性能,因为当字符串非空时,至少有一个字符,所以从1开始可以减少一些不必要的比较和更新。
所以,修改你的版本,将expandAroundCenter的参数改为const string&,并且将maxlen初始化为1,同时去掉多余的max调用,应该可以得到相似的性能。
让我们修改你的版本:
修改后:
- 将
expandAroundCenter的参数类型从string s改为const string& s
- 将
maxlen初始化为1
- 在更新
maxlen时,直接赋值maxlen = len3;,因为已经确定len3 > maxlen