5. 最长回文子串
给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
回文的意思是正着念和倒着念一样,如:上海自来水来自海上
示例 1:
输入: “babad”
输出: “bab”
注意: “aba” 也是一个有效答案。
示例 2:
输入: “cbbd”
输出: “bb”
方法一:暴力循环法
因为回文满足对称性,所以我们可以对每次截取的字符串,设置两个指针,对头部和尾部同时进行判断,当出现头部和尾部不匹配的情况,则不是回文串,若为全部匹配没有发现,则为回文串。
每次对测试成功的串进行长度统计,最终返回最长的一个回文串长度。
public String longestPalindrome(String s) {
int i,j;
String end = "";
int result = 0;
String a;
if(s.length() == 1)return s;
else {
for (i = 0;i<s.length();i++) {
for (j = i+1;j<=s.length();j++) {
a = s.substring(i, j);///不包含??
if (test(a)&&a.length()>result) {
result = a.length();
end = a;
}
}
}
return end;
}
}
public boolean test(String s) {
int a = s.length();
int g = 0,key = 0;
for (g = 0;g < a/2;g++) {
if (s.charAt(g)!=s.charAt(a-g-1))return false;
}
return true;
}
因为使用了三重循环,所以时间复杂度为 O(n³),空间复杂度为O(1).
运行结果:
超出时间限制
输入:
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"
代码优化的思路就是:将substring更换为两根指针可能会解决问题。以后留时间解决。
方法二:中心扩展算法
同样的,回文满足对称性,原来我们是对子串进行单独处理判断,现在换一种思路,每次选择一个中心对称轴,对中心对称轴两边进行扩展,最后算出长度,接下来就是对end 和star 的更新,最后由star 和 end来确认字符串的起始和结束位置
public int findcentrol(int left,int right,String s) {
int L = left;
int R = right;
while(L>=0&&R<s.length()&&s.charAt(L)==s.charAt(R)) {
L--;
R++;
}
int length = R-L-1;
return length;
}
public String solution(String s) {
if (s.length()<1||s== null)return"";
else {
int i;
int result,start = 0,end= 0;
for (i = 0;i<s.length();i++) {
int length1 = findcentrol(i, i, s);////判断在一个字符为中心时候的回文长度类似于'aba'
int length2 = findcentrol(i, i+1, s);////判断在两个字符为中心时候的回文长度,类似于'abba'
result = Math.max(length1, length2);
if (result>end-start) {
end = i+result/2;
start = i-(result-1)/2;
}
}
return s.substring(start,end+1);
}
}
运行结果
103 / 103 个通过测试用例
状态:通过
执行用时:33 ms
内存消耗:37.9 MB
其他还有三种方法本次暂时不加赘述,下次将会补充。
遇到的问题
- substring(i,j)代表截取的字符串位置包含从i位到j-1位,不包含j位。