描述
分析
拿到这道题的时候,我想到了三种方法:
- 暴力法,时间复杂度 ,显然不可取
- 将字符串翻转,而后便转为求最长公共子序列的问题,时间复杂度
- 中心拓展,依次判断,时间复杂度
在写代码的时候我用了第三种方法,本以为可以通过全部测试用例,却卡在了92/103,这里先贴出我的代码
代码
class Solution {
public:
string longestPalindrome(string s) {
if (s.empty()) return "";
int length = s.length();
string longest;
for (int i = 0;i < length;i++) {
string tmp;
int left = i - 1, right = i + 1;
tmp.push_back(s[i]);
while (left >= 0 && s[left] == s[i]) tmp = s[left--] + tmp;
while (right < length && s[right] == s[i]) tmp = s[right++] + tmp;
for (int j = right, k = left;k >= 0 && j < length;j++, k--) {
if (s[j] == s[k])
tmp = s[j] + tmp + s[j];
else break;
}
if (tmp.length() > longest.length())
longest = tmp;
}
return longest;
}
};
我的这个代码大量利用了临时存储空间,同时由于反复的比较、赋值操作导致了大量的时空开销。虽然想法问题不大,但还是不能通过。
官方给出的解法是使用两个变量记录最长回文子串的初始与截止下标,每在一个字符(或两个,因为可能出现abba的情况,此时中心点在两个b之间)上扩展一个新的回文串,都将此串长度与最大长度比较,若大于则替换。
这样的方法比我的要明智的多。
代码
public String longestPalindrome(String s) {
if (s == null || s.length() < 1) return "";
int start = 0, end = 0;
for (int i = 0; i < s.length(); i++) {
int len1 = expandAroundCenter(s, i, i);
int len2 = expandAroundCenter(s, i, i + 1);
int len = Math.max(len1, len2);
if (len > end - start) {
start = i - (len - 1) / 2;
end = i + len / 2;
}
}
return s.substring(start, end + 1);
}
private int expandAroundCenter(String s, int left, int right) {
int L = left, R = right;
while (L >= 0 && R < s.length() && s.charAt(L) == s.charAt(R)) {
L--;
R++;
}
return R - L - 1;
}
/*
作者:LeetCode
链接:https://leetcode-cn.com/problems/longest-palindromic-substring/solution/zui-chang-hui-wen-zi-chuan-by-leetcode/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。
*/