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

https://leetcode.com/problems/longest-palindromic-substring/

求最大回文的长度,其实这道题比上一道有意思。

方法1 循环查询 (该方案为O(N*N*N))

public static boolean isPalindrome(String s, int start, int end) {
if (((end - start) & 0x1) == 1) {
while (start + 1 != end) {
if (s.charAt(start++) != s.charAt(end--)) {
return false;
}
}
return s.charAt(start) == s.charAt(end);
} else {
while (start != end) {
if (s.charAt(start++) != s.charAt(end--)) {
return false;
} }
} return true;
} public static String longestPalindrome_1(String s) {
int len = s.length();
if (len < 2) {
return s;
}
for (int i = 0, end=len/2; i < end; i++) {
for (int j = len - 1, k = i; k > -1; j--, k--) {
if (k == j && j == i) {
return "";
}
if (isPalindrome(s, k, j)) {
return s.substring(k, j + 1);
}
}
} return "";
}

方法2 动态规划 (该方案为O(N*N))

由于没学过动态规划,特意去学习了一下

/**
*
* 1. 初始条件:
空串 看作是回文的最初始条件,LP[i][i-1]=1。这作为初始状态,并不认为是有回文。
单字符串 是直接认为有回文的,LP[i][i]=1。
2. 状态转移:
若LP[i][j]=1且a[i-1]==a[j+1] ,那么有LP[i-1][j+1]=1,否则LP[i-1][j+1]=0
* @param s
* @return
*/
public static String longestPalindromeDP_2(String s) {
int n = s.length();
int longestBegin = 0;
int maxLen = 1;
boolean[][] table = new boolean[n][n];
// 单字符
for (int i = 0; i < n; i++) {
table[i][i] = true;
}
// 双字符
for (int i = 0; i < n - 1; i++) {
if (s.charAt(i) == s.charAt(i + 1)) {
table[i][i + 1] = true;
longestBegin = i;
maxLen = 2;
}
}
// 子串长度
for (int len = 3; len <= n; len++) {
// 子串的起始位置
for (int i = 0; i < n - len + 1; i++) {
// 子串的结束位置
int j = i + len - 1;
// DP条件
if (table[i + 1][j - 1] && s.charAt(i) == s.charAt(j) ) {
table[i][j] = true;
longestBegin = i;
maxLen = len;
}
}
}
return s.substring(longestBegin, longestBegin + maxLen);
}

方法3 中心扩展,方法1的优化版本 (该方案为O(N*N))

static class Pair {
int s;
int e; public Pair(int s, int e) {
this.s = s;
this.e = e;
} int length() {
return e - s + 1;
}
} public static Pair expandAroundCenter2(String s, int c1, int c2) {
int l = c1, r = c2;
int n = s.length();
while (l > -1 && r < n && s.charAt(l) == s.charAt(r)) {
l--;
r++;
}
return new Pair(l + 1, r);
} public static String longestPalindromeSimple2(String s) {
int n = s.length();
if (n == 0)
return "";
Pair longest = new Pair(0, 1); // a single char itself is a
// palindrome
int i = 0;
// 偶回文
Pair p2 = expandAroundCenter2(s, i, i + 1);
if (p2.length() > longest.length())
longest = p2;
for (i = 1; i < n - 1; i++) {
// 奇回文
Pair p1 = expandAroundCenter2(s, i, i);
if (p1.length() > longest.length())
longest = p1;
// 偶回文
p2 = expandAroundCenter2(s, i, i + 1);
if (p2.length() > longest.length())
longest = p2;
}
return s.substring(longest.s,longest.e);
}

方法.后缀数组, logN * O(n)

方法5.Manacher算法, O(n)

// ^ and $ 避免空指针
static StringBuilder preProcess(String s) {
int n = s.length();
StringBuilder buff = new StringBuilder("^");
for (int i = 0; i < n; i++) {
buff.append("#").append(s.charAt(i));
}
buff.append("#$");
return buff;
}
public static String longestPalindrome(String s) {
if (s.length() < 2) {
return s;
}
// 插入到^#c#a#b#b#a#$
StringBuilder T = preProcess(s);
int length = T.length();
int[] p = new int[length]; //存储每一个位置的长度
int C = 0, R = 0; for (int i = 1; i < length - 1; i++) { int i_mirror = C - (i - C);
int diff = R - i;
// prettyPrint(T, C, R, i, i_mirror, p);
if (diff >= 0)// 当前i在C和R之间,可以利用回文的对称属性
{
// R 能移动已经判断是相等过
if (p[i_mirror] < diff)// i的对称点的回文长度在C的大回文范围内部
{
p[i] = p[i_mirror];
// System.out.println(T.charAt(i_mirror) + "<<$>>"+ T.charAt(i));
} else {
p[i] = diff;
// i处的回文可能超出C的大回文范围了
while (T.charAt(i + p[i] + 1) == T.charAt(i - p[i] - 1)) {
p[i]++;
}
C = i;
R = i + p[i];
}
} else {
p[i] = 0;
while (T.charAt(i + p[i] + 1) == T.charAt(i - p[i] - 1)) {
p[i]++;
}
C = i;
R = i + p[i];
}
} int maxLen = 0;
int centerIndex = 0;
// 最大的索引
for (int i = 2; i < length - 1; i+=1) {
if (p[i] > maxLen) {
maxLen = p[i];
centerIndex = i;
}
}
// 计算起始地址
centerIndex = (centerIndex - 1 - maxLen) / 2;
return s.substring(centerIndex, centerIndex + maxLen);
}

  

【leedcode】 Longest Palindromic Substring的更多相关文章

  1. 【LeetCode】Longest Palindromic Substring 解题报告

    DP.KMP什么的都太高大上了.自己想了个朴素的遍历方法. [题目] Given a string S, find the longest palindromic substring in S. Yo ...

  2. 【leetcode】Longest Palindromic Substring (middle) 经典

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  3. 【翻译】Longest Palindromic Substring 最长回文子串

    原文地址: http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-i.html 转载请注明出处:http:// ...

  4. Leetcode:【DP】Longest Palindromic Substring 解题报告

    Longest Palindromic Substring -- HARD 级别 Question SolutionGiven a string S, find the longest palindr ...

  5. 【LeetCode5】Longest Palindromic Substring★★

    1.题目描述: 2.解题思路: 题意:求一个字符串的最长回文子串. 方法一:中心扩展法.遍历字符串的每一个字符,如果存在回文子串,那么中心是某一个字符(奇数)或两个字符的空隙(偶数),然后分两种情况( ...

  6. 【Leetcode】Longest Palindromic Substring

    问题:https://leetcode.com/problems/longest-palindromic-substring/ 给定一个字符串 S,求出 S 的最长回文子串 思路: 1. 回文:一个字 ...

  7. 【SPOJ】Longest Common Substring II (后缀自动机)

    [SPOJ]Longest Common Substring II (后缀自动机) 题面 Vjudge 题意:求若干个串的最长公共子串 题解 对于某一个串构建\(SAM\) 每个串依次进行匹配 同时记 ...

  8. 【SPOJ】Longest Common Substring(后缀自动机)

    [SPOJ]Longest Common Substring(后缀自动机) 题面 Vjudge 题意:求两个串的最长公共子串 题解 \(SA\)的做法很简单 不再赘述 对于一个串构建\(SAM\) 另 ...

  9. 【SPOJ】Longest Common Substring II

    [SPOJ]Longest Common Substring II 多个字符串求最长公共子串 还是将一个子串建SAM,其他字符串全部跑一边,记录每个点的最大贡献 由于是所有串,要对每个点每个字符串跑完 ...

随机推荐

  1. AngularJS 表格

    ng-repeat 指令可以完美的显示表格. 使用 angular 显示表格是非常简单的: <!DOCTYPE html> <html> <head> <me ...

  2. 在CentOS7上安装Docker

    具体过程如下 到网站下载centos7: http://isoredirect.centos.org/ http://isoredirect.centos.org/centos/7/isos/x86_ ...

  3. 大部分人都会做错的经典JS闭包面试题

    由工作中演变而来的面试题 这是一个我工作当中的遇到的一个问题,似乎很有趣,就当做了一道题去面试,发现几乎没人能全部答对并说出原因,遂拿出来聊一聊吧. 先看题目代码: function fun(n,o) ...

  4. Python学习笔记(五)——list和tuple

    一.list 1.定义: list是一种有序的集合,可以随时添加和删除其中的元素 2.声明方法: subjects=['Math','English', 'Chinese'] 3.一些api (1)获 ...

  5. SpringMvc的创建流程以及2种加载配置文件的方式

    1.首先创建个web项目,第一步导入相应的jar包,并且buildtoPath 2.用elipse或myeclipse点击进入web.xml中 按住 Alt+ / 有个提示 找到前面带 #Dispat ...

  6. IE8+兼容经验小结

    最近一段时间,我都使用Flask+Bootstrap3的框架组合进行开发.本文就是在这种技术组合下,分享IE8+兼容性问题的解决方法.根据我的实践经验,如果你在写HTML/CSS时候是按照W3C推荐的 ...

  7. 【Oracle】oracle中rownum的说明及使用技巧

    oracle中常用到ROWNUM,所以做一些本人对rownum的一些认识和使用技巧的记录,以便备查. 一.rownum的说明 rownum是oracle特有的一个关键字. (1)对于基表,在inser ...

  8. Leetcode Valid Number

    Validate if a given string is numeric. Some examples:"0" => true" 0.1 " => ...

  9. Python开发: DOM

    文档对象模型(Document Object Model,DOM)是一种用于HTML和XML文档的编程接口.它给文档提供了一种结构化的表示方法,可以改变文档的内容和呈现方式.我们最为关心的是,DOM把 ...

  10. dblink嵌套场景下 查询出现:ORACLE ORA-00600错误的解决

    前段时间在做oracle查询的时候遇到了一个非常奇怪的现象,现将现象和解决过程记录下来,以备查看: 环境描述:A数据库通过dblink访问B数据库的视图,B数据库的视图的数据是通过B的dblink连接 ...