Longest Palindromic Substring

题目:

Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

分析:

该题使用Manacher算法,首先为了避免字符串个数成奇数或偶数的问题,在每个字符两边加上字符串不存在的符号,我这使用了#,还有为了防止判断字符串为回文串是向两边延伸时出现数组溢出异常,在首尾两头可以加上不同的字符,并且首尾两新增字符不参与是否回文串判断。

本算法的核心是:

if (maxid > i) {
	longest[i] = Math.min(longest[2 * id - i], maxid - i);
} else {
	longest[i] = 1;
}
这是考虑到回文字符串的对称性,首先定义了id,maxid两个变量,定义一个最终对称点位置变量longestStr和以该对称点为位置的最长回文串长度。id就是指前一次非1长度回文串的对称点,maxid就是该对称点的最长延伸(maxid=id+longest[id]-1)(longest[i]表示以i点为对称点的回文字符串半径)。遍历字符串,当maxid>i表示当前点在前一次回文字符串内,然后我们就可以找到当前点关于id的对称点2*id-i,根据对称性,i与2*id-i点的回文串半径在基于前一次回文串内是相同的,但是考虑到i+longest[2*id-i]会超出maxid,所以利用min(2*id-i,maxid-i)加以限制。

代码:

public class Solution {
    public String longestPalindrome(String s) {
		String strs = newString(s).toString();
		char[] str = strs.toCharArray();
		int[] longest = new int[strs.length()];
		int id = 0, maxid = 0;
		int maxLongest = 0;
		int longestStr = 0;// 最终对称点位置
		for (int i = 0; i < str.length; i++) {
			if (maxid > i) {
				longest[i] = Math.min(longest[2 * id - i], maxid - i);
			} else {
				longest[i] = 1;
			}
			while (0 < i && i < str.length - 1 && str[i + longest[i]] == str[i - longest[i]]) {//首尾两头不进行比较
				longest[i]++;
			}
			if (longest[i] + i - 1> maxid) {
				maxid = longest[i] + i - 1;
				id = i;
			}
			if (maxLongest < longest[i]) {
				maxLongest = longest[i];
				longestStr = i;
			}
		}
		String longString = strs.substring(longestStr - longest[longestStr] + 1, longestStr + longest[longestStr]);
		return longString.replace("#", "").trim();
	}

	public StringBuffer newString(String s) {
		char[] str = s.toCharArray();
		StringBuffer sb = new StringBuffer();
		sb.append("@#");
		for (int i = 0; i < str.length; i++) {
			sb.append(str[i]).append("#");
		}
		sb.append("$");
		return sb;
	}
}


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值