<div class="iteye-blog-content-contain" style="font-size: 14px"></div>
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.
[balabala] Method1从小到大逐一check不同长度的子串是否为回文,使用DP保存中间计算,但仍然会超时,Method3是非DP版的Method1,1年前的历史记录竟然是Accept的,估计当时leetcode 打瞌睡了。Method2 同样是DP,能够被Accept,分析计算次数和Method1一样,在Eclipse下实际运行超时的case,后者比前者快三、四ms,我认为差异主要是因为Method1 访问数组的模式不如Method2优,将二维数组看成一个矩阵,Method1 不断在各行间跳跃访问,而Method2 在一次外层循环中逐列访问同一行的数组。Method4是从当前1个字符或当前两个字符向两边辐射求得最长回文,该方法比Method2效率更高,因为它避免了一些无意义的计算,比如“abcdefg”, Method1和2均需要计算全部子串,而Method4不会计算诸如abcde这样的子串,在计算bcd时即停止计算其余以c为中心的子串。还有一种[color=red]O(n)的实现[/color],还未看懂,[url]http://www.cnblogs.com/tenosdoit/p/3675788.html[/url] 先备忘着。
[ref]
[url]http://www.cnblogs.com/tenosdoit/p/3675788.html[/url]
[url]http://www.cnblogs.com/jdflyfly/p/3810674.html[/url]
[url]http://codeganker.blogspot.com/2014/02/longest-palindromic-substring-leetcode.html[/url]
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.
[balabala] Method1从小到大逐一check不同长度的子串是否为回文,使用DP保存中间计算,但仍然会超时,Method3是非DP版的Method1,1年前的历史记录竟然是Accept的,估计当时leetcode 打瞌睡了。Method2 同样是DP,能够被Accept,分析计算次数和Method1一样,在Eclipse下实际运行超时的case,后者比前者快三、四ms,我认为差异主要是因为Method1 访问数组的模式不如Method2优,将二维数组看成一个矩阵,Method1 不断在各行间跳跃访问,而Method2 在一次外层循环中逐列访问同一行的数组。Method4是从当前1个字符或当前两个字符向两边辐射求得最长回文,该方法比Method2效率更高,因为它避免了一些无意义的计算,比如“abcdefg”, Method1和2均需要计算全部子串,而Method4不会计算诸如abcde这样的子串,在计算bcd时即停止计算其余以c为中心的子串。还有一种[color=red]O(n)的实现[/color],还未看懂,[url]http://www.cnblogs.com/tenosdoit/p/3675788.html[/url] 先备忘着。
[ref]
[url]http://www.cnblogs.com/tenosdoit/p/3675788.html[/url]
[url]http://www.cnblogs.com/jdflyfly/p/3810674.html[/url]
[url]http://codeganker.blogspot.com/2014/02/longest-palindromic-substring-leetcode.html[/url]
// Method 1: O(n^2), time out
public String longestPalindrome1(String s) {
if (s == null || s.equals(""))
return "";
int n = s.length();
boolean[][] dp = new boolean[n][n];
for (int i = 0; i < n; i++)
dp[i][i] = true;
String ans = s.substring(0, 1);
for (int i = 0; i < n - 1; i++) {
dp[i][i + 1] = s.charAt(i) == s.charAt(i + 1);
if (ans.length() == 1 && dp[i][i + 1])
ans = s.substring(i, i + 2);
}
for (int l = 3; l <= n; l++) {
for (int i = 0; i + l <= n; i++) {
int j = i + l - 1;
dp[i][j] = s.charAt(i) == s.charAt(j) && dp[i + 1][j - 1];
if (ans.length() < l && dp[i][j])
ans = s.substring(i, i + l);
}
}
return ans;
}
// Method 2: O(n^2) 另一种DP实现
// http://codeganker.blogspot.com/2014/02/longest-palindromic-substring-leetcode.html
public String longestPalindrome(String s) {
if (s == null || s.equals(""))
return "";
int n = s.length();
String ans = "";
int maxLen = 0;
boolean[][] dp = new boolean[n][n];
for (int i = n - 1; i >= 0; i--) {
for (int j = i; j < n; j++) {
if (s.charAt(i) == s.charAt(j) && (j - i < 2 || dp[i + 1][j - 1])) {
dp[i][j] = true;
if (maxLen < j - i + 1) {
maxLen = j - i + 1;
ans = s.substring(i, j + 1);
}
}
}
}
return ans;
}
// Method 3: O(n^2), from up to bottom, once accept, time out now
public String longestPalindrome3(String s) {
if (s == null || s.equals(""))
return "";
int n = s.length();
for (int len = n; len >= 1; len--) {
for (int i = 0; i + len <= n; i++) {
String sub = s.substring(i, i + len);
if (isPalin(sub)) {
return sub;
}
}
}
return "";
}
private boolean isPalin(String s) {
int i = 0, j = s.length() - 1;
while (i < j) {
if (s.charAt(i) != s.charAt(j))
return false;
i++;
j--;
}
return true;
}
// Method 4: O(n^2) 以当前字符或者当前字符及下一个字符向外辐射找出最长的子串
// http://www.cnblogs.com/jdflyfly/p/3810674.html
public String longestPalindrome4(String s) {
if (s == null || s.equals(""))
return "";
int n = s.length();
int maxLen = 1;
int tmpLen = 0;
String ans = s.substring(0, 1);
for (int i = 0; i < n - 1; i++) {
tmpLen = getPalin(s, i - 1, i + 1);
if (tmpLen > maxLen) {
int start = i - tmpLen / 2;
ans = s.substring(start, start + tmpLen);
maxLen = tmpLen;
}
tmpLen = getPalin(s, i, i + 1);
if (tmpLen > maxLen) {
int start = i - tmpLen / 2 + 1;
ans = s.substring(start, start + tmpLen);
maxLen = tmpLen;
}
}
return ans;
}
private int getPalin(String s, int left, int right) {
int n = s.length();
int len = right - left - 1;
while (left >= 0 && right < n) {
if (s.charAt(left--) == s.charAt(right++)) {
len += 2;
} else {
return len;
}
}
return len;
}