您的位置:首页 > 其它

LeetCode 5. Longest Palindromic Substring(最长回文子串)

2016-05-19 03:25 1011 查看
原题网址:https://leetcode.com/problems/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.

方法一:动态规划,从2~s.length()逐层检查是否对称,对于每一个长度,从左到右扫描。由于回文子串可能为奇数长度或者偶数长度,所以需要确认两个长度都无法检测到对称,程序才终止。

public class Solution {
public String longestPalindrome(String s) {
if (null == s || "".equals(s)) return s;
boolean[][] palindromic = new boolean[s.length()+1][s.length()];
for(int j=0; j<s.length(); j++) {
palindromic[0][j] = true;
palindromic[1][j] = true;
}
boolean found;
int maxLength = 1;
int maxFrom = 0;
int missing = 0;
for(int i=2; i<=s.length(); i++) {
found = false;
for(int j=0; j<=s.length()-i; j++) {
palindromic[i][j] = palindromic[i-2][j+1] & (s.charAt(j) == s.charAt(j+i-1));
if (palindromic[i][j]) {
found = true;
if (i>maxLength) {
maxLength = i;
maxFrom = j;
}
}
}
if (found) missing = 0;
else missing ++;

if (missing >= 2) break;
}
return s.substring(maxFrom, maxFrom + maxLength);
}
}


方法二:从左到右扫描中心点,对于每个中心点,从小到大检查是否对称。

public class Solution {
public String longestPalindrome(String s) {
char[] sarray = s.toCharArray();
if (sarray.length == 1) return s;
int pos = 0;
int len = 0;
for(int i=1; i+len/2<sarray.length; i++) {
for(int j=1; i-j>=0 && i+j<=sarray.length-1; j++) {
if (sarray[i-j] != sarray[i+j]) break;
if (j*2+1 > len) {
len = j*2+1;
pos = i-j;
}
}
}
for(int i=0; i+1+len/2<sarray.length; i++) {
for(int j=0; i-j>=0 && i+j+1<sarray.length; j++) {
if (sarray[i-j] != sarray[i+j+1]) break;
if ((j+1)*2 > len) {
len = (j+1)*2;
pos = i-j;
}
}
}
return s.substring(pos, pos+len);
}
}


方法三:Manacher算法。

public class Solution {
/*
根据Manacher算法自己编写,参考: http://blog.vars.me/blog/2015/04/12/Manachers-algorithm-Longest-palindromic-substring/ */
public String longestPalindrome(String s) {
char[] origin = s.toCharArray();
char[] sarray = new char[origin.length * 2 + 1];
sarray[0] = '#';
int pos = 1;
for(int i=0; i<origin.length; i++) {
sarray[pos++] = origin[i];
sarray[pos++] = '#';
}
int[] radius = new int[sarray.length];
int maxRadius = 0;
int maxPos = 0;
int maxRight = 0;
int maxCenter = 0;
for(int i=1; i<sarray.length-1; i++) {
if (i < maxRight) {
int j=maxCenter - (i-maxCenter);
radius[i] = Math.min(radius[j], maxRight - i);
}
// 这个是关键,因为半径小于radius[i]的部分已经不需要判断
for(int m = radius[i]+1; i - m >= 0 && i + m <= sarray.length-1; m ++) {
if (sarray[i-m] != sarray[i+m]) break;
radius[i] = m;
}
if (i+radius[i] > maxRight) {
maxRight = i + radius[i];
maxCenter = i;
}
if (radius[i] > maxRadius) {
maxRadius = radius[i];
maxPos = i;
}
// System.out.printf("i=%d, s[i]=%c, radius[i]=%d, maxRadius=%d, maxPos=%d, maxCenter=%d, maxRight=%d\n", i, sarray[i], radius[i], maxRadius, maxPos, maxCenter, maxRight);
}
char[] longest = new char[maxRadius];
pos = 0;
for(int i=maxPos-maxRadius; i<=maxPos+maxRadius; i++) {
if (sarray[i] != '#') longest[pos++] = sarray[i];
}
return new String(longest);
}
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: