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. ORA-27101: shared memory realm does not exist

    Oracle Error Tips by Burleson Consulting Oracle docs note this about ORA-27101: ORA-27101: shared me ...

  2. MapReduce类型与格式(输入与输出)

    一.输入格式 (1)输入分片记录 ①JobClient通过指定的输入文件的格式来生成数据分片InputSplit: ②一个分片不是数据本身,而是可分片数据的引用: ③InputFormat接口负责生成 ...

  3. kafka与传统的消息中间件对比

    RabbitMQ和kafka从几个角度简单的对比 业界对于消息的传递有多种方案和产品,本文就比较有代表性的两个MQ(rabbitMQ,kafka)进行阐述和做简单的对比, 在应用场景方面, Rabbi ...

  4. ActiveMQ初体验(转)

    转载地址:http://www.cnblogs.com/diorlv/p/3328712.html 做了修改 首先介绍下MQ,MQ英文名MessageQueue,中文名也就是大家用的消息队列,干嘛用的 ...

  5. for循环中i--的妙用 及 两变量互换数值的问题

    int[] array = new int[4]; for(int i = 0; i < array.length; i++){ array[i] = (int)(Math.random() * ...

  6. pyqt5 开发环境

    pyqt5 pycharm mac下开发环境 brew install python3 安装python3 brew install pyqt5 配置pycharm http://blog.csdn. ...

  7. sqlmap和burpsuite绕过csrf token进行SQL注入检测

    利用sqlmap和burpsuite绕过csrf token进行SQL注入 转载请注明来源:http://www.cnblogs.com/phoenix--/archive/2013/04/12/30 ...

  8. [工作中的设计模式]组合模式compnent

    一.模式解析 将对象组合成树形结构以表示“部分整体”的层次结构.组合模式使得用户对单个对象和使用具有一致性. 组合模式的要点是: 1.对象整体以树形层次结构进行展示 2.树的根节点和子节点均可以添加删 ...

  9. 同步、更新、下载Android Source & SDK from 国内镜像站(转载)

    同步.更新.下载Android Source & SDK from 国内镜像站 转自: 同步.更新.下载Android Source & SDK from 国内镜像站 Download ...

  10. HBase如何选取split point

    hbase region split操作的一些细节,具体split步骤很多文档都有说明,本文主要关注regionserver如何选取split point 首先推荐web ui查看hbase regi ...