给定一个字符串 s
,找到 s
中最长的回文子串。你可以假设 s
的最大长度为 1000。
示例 1:
1 2 3
| 输入: "babad" 输出: "bab" 注意: "aba" 也是一个有效答案。
|
示例 2:
在看这个问题之前我们首先来看看如何判断回文字符串,我们很容易写出下面的代码。
1 2 3 4 5 6 7 8
| boolean isPalindrome(String s){ for(int i=0, j=s.length()-1; i<j; ++i,--j){ if(s.charAt(i) != s.charAt(j)){ return false; } } return true; }
|
可以看出,回文字符串是关于一个字符或者最中心的两个字符左右对称的。
- 当字符串中字符数为奇数时关于最中心的字符对称,例如 abcba 关于字符 c 对称。
- 当字符串中字符数为偶数时关于最中心的两个字符之间的空格对称,例如 abba 关于 bb 对称。
一个字符数为 n 的字符串可以关于 n 个单字符对称,关于 n-1 个两个字符对称。我们只需遍历 2n - 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
| class Solution { 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 = expandAround(s,i,i); int len2 = expandAround(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 expandAround(String s, int left, int right){ while(left >=0 && right<s.length() && s.charAt(left) == s.charAt(right)){ left--; right++; }
return right-left-1; } }
|
时间复杂度 O(n^2),空间复杂度O(1)。