leetcode-5-最长回文子串(longest palindromic substring)-java

版权声明:此文章为许诗宇所写,如需转载,请写下转载文章的地址 https://blog.csdn.net/xushiyu1996818/article/details/83787304

题目及测试

package pid005;
/*最长回文子串

给定一个字符串 s,找到 s 中最长的回文子串。你可以假设 s 的最大长度为1000。

示例 1:

输入: "babad"
输出: "bab"
注意: "aba"也是一个有效答案。

示例 2:

输入: "cbbd"
输出: "bb"






*/
public class main {
	
	public static void main(String[] args) {
		String[] testTable = {"babad","cbbd","ccc","eabcb"};
		for (int i=0;i<testTable.length;i++) {
			test(testTable[i]);
		}
	}
		 
	private static void test(String ito) {
		Solution solution = new Solution();
		String rtn;
		long begin = System.currentTimeMillis();
		System.out.println("ito="+ito);
		rtn = solution.longestPalindrome(ito);//执行程序
		long end = System.currentTimeMillis();		
		System.out.println("rtn="+rtn);
		System.out.println();
		System.out.println("耗时:" + (end - begin) + "ms");
		System.out.println("-------------------");
	}

}

解法1(成功,138ms,很慢)
对0到length-1进行循环(不能循环到中间,因为字符串后半段也有可能有会文字符串)
对每个index,进行奇数会文和偶数会文的判断,奇数是两边相等,偶数是自身与右边相等
记录max的length和substring

package pid005;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Queue;
import java.util.concurrent.LinkedBlockingQueue;

public class Solution {
public String longestPalindrome(String s) {
    int length=s.length();
    if(length<=1){
    	return s;
    }
    int maxLength=0;
    String maxString="";
    for(int i=0;i<length;i++){//4 2(1)  5 3(2)
    	//首先检查以自己为中心(奇数会文)
    	int j=1;
    	int nowlength=1;
    	while(i-j>=0&&i+j<length){
    		if(s.charAt(i-j)==s.charAt(i+j)){
    			j++;
    			nowlength=nowlength+2;
    		}
    		else{
    			break;
    		}
    	}    	
    	if(nowlength>maxLength){
    		maxString=s.substring(i-(int)Math.floor(nowlength/2), i+(int)Math.floor(nowlength/2)+1);
    		maxLength=nowlength;
    	}
    	//检查偶数会文
    	j=0;
    	nowlength=0;
    	while(i-j>=0&&i+j+1<length){
    		if(s.charAt(i-j)==s.charAt(i+j+1)){
    			j++;
    			nowlength=nowlength+2;
    		}
    		else{
    			break;
    		}
    	}
    	if(nowlength>maxLength){
    		maxLength=nowlength;
    		maxString=s.substring(i-nowlength/2+1, i+nowlength/2+1);
    	}
    	
    }
    
	return maxString;
    }

}

解法2(别人的)

动态规划:

(一般含“最XX”等优化词义的题意味着都可以动态规划求解),时间复杂度O(n^2),空间复杂度O(n^2)。
 形如"abba", "abbba"这样的字符串,如果用dp[i][j]表示从下标i到j之间的子字符串所构成的回文子串的长度,则有:
 dp[i][j] = dp[i+1][j-1] && s[i] == s[j]
初始化:
 奇数个字符:dp[i][i] = 1; 偶数个字符:dp[i][i+1] = 1
若长度相同,返回最后一个子串
 

public String longestPalindrome(String s) {
		if (s == null || s.length() <= 1)
			return s;
		int n = s.length();
		char[] cs = s.toCharArray();
		int max = 1;
		int maxIndex = 0;
		boolean dp[][] = new boolean[n][n];
		// 初始化一个字母
		for (int i = 0; i < n; i++) {
			dp[i][i] = true;
			maxIndex = i;
		}
		// 初始化两个相同的字母"aa"
		for (int i = 0; i < n - 1; i++)
			if (cs[i] == cs[i + 1]) {
				dp[i][i + 1] = true;
				// 返回最后一为2的子串
				max = 2;
				maxIndex = i;
			}
		// 从长度3开始操作, (aba)ba, a(bab)a, ab(aba)
		for (int len = 3; len <= n; len++)
			for (int i = 0; i < n - len + 1; i++) {
				// j为从i~i + len - 1下标,长度为len
				int j = i + len - 1;
				// 字符相同,并且内部长度是回文
				if (cs[i] == cs[j] && dp[i + 1][j - 1]) {
					max = len;
					// 因为长度递增,如果之后的的能进入这里都是比之前长的,
					// 所以不需要判断大小
					maxIndex = i;
					dp[i][j] = true;
				}
			}
		return s.substring(maxIndex, maxIndex + max);
	}

解法3(别人的)

使用manacher算法

https://www.cnblogs.com/z360/p/6375514.html

http://blog.sina.com.cn/s/blog_70811e1a01014esn.html

猜你喜欢

转载自blog.csdn.net/xushiyu1996818/article/details/83787304