给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为 1000。
示例:
输入: "babad"
输出: "bab"
注意: "aba" 也是一个有效答案。
输入: "cbbd"
输出: "bb"
来源:力扣(LeetCode)
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
暴力解法: 遍历判断:先从两边向内查找相等的字符 S(i,j)【表示第i个和第j个两个字符】,再判断S(i+1,j-1)是否相等。以此类推,直到i>=j。
public String longestPalindrome(String s) {
char[] chars = s.toCharArray();
int indexLeft = 0,indexRight = 0;
for (int i = 0; i <chars.length ; i++) {
for (int j = chars.length-1 ; j > i ; j--) {
if(chars[i]==chars[j]){
boolean palindrome = isPalindrome(s.substring(i, j+1));
if(palindrome&&j-i>indexRight-indexLeft){
indexLeft = i;
indexRight = j;
break;
}
}
}
}
return s.substring(indexLeft,indexRight+1);
}
public boolean isPalindrome(String s){
char[] chars = s.toCharArray();
for (int i = 0; i <chars.length ; i++) {
if(chars[i]==chars[chars.length-1-i] && s.length()>1){
if(!isPalindrome(s.substring(1,chars.length-1))){
return false;
}
}else if(chars[i]!=chars[chars.length-1-i] ) {
return false;
}
}
return true;
}
毫无疑问的处理超时了。。。
原因分析:由于查找第一个相等的字符时进行了2重循环,判断是否为回文时进行了1次循环,所以他的时间复杂度为 O(n3)。(还未计算 递归算法。。。),只能用于提供思路,实操请绕行。
动态规划算法
由以上暴力解法中可以得知:如果F[i,j]是回文,那么F[i+1,j-1]也是回文。
- i,j:表示第i个和第j个字符
- S[i,j]:表示第i个和第j个字符是否回文,是为true,否为false
- F[i,j]:表示从i到j的字符串是否回文,是为true,否为false
- +号:表示代码中的 &&
public String longestPalindrome(String s) {
int length = s.length();
// 动态规划:F[i,j]=F[i+1,j−1] && S[i,j]
boolean[][] dp = new boolean[length][length];
int indexLeft = 0,indexRight = 0;
//len 表示跨度 即选择的字符长度
for (int len = 0; len < length ; len++) {
for (int start = 0 ; start < length; start++) {
int end = start+len;
if(end<length){
if(len==0){
// len = 0 单个字符都是回文,所以全为true
dp[start][end] = true;
}else {
boolean flag = s.charAt(start) == s.charAt(end);
if(len == 1){
// len = 1 两个字符,直接判断是否相等即可
dp[start][end] = flag;
}else {
// 更多字符 判断当前字符是否为回文,还要判断上两个字符是否为回文
dp[start][end] = flag && dp[start + 1][end - 1];
}
}
if (dp[start][end] && end - start + 1 > indexRight-indexLeft) {
indexLeft = start;
indexRight = end+1;
}
}
}
}
return s.substring(indexLeft,indexRight);
}
一顿操作猛如虎,一看超过九点五。。。
不服!再优化!