找到最长的回文子串
Posted
技术标签:
【中文标题】找到最长的回文子串【英文标题】:Find the longest pallindrome substring 【发布时间】:2015-08-04 06:51:21 【问题描述】:给定一个字符串,找出最长的回文子串。例如,如果给定的字符串是“forgeeksskeegfor”,则输出应该是“geeksskeeg”。
我是怎么做的? 我只知道如何找到回文即
给定一个字符串。我从 0 和长度-1 开始获取 2 个索引 i,j。比较给定索引处存在的两个字符直到 i
这是我的代码
class StringPallendrome
static int length = 0;
static int Count=0;
static boolean stringpallendrome(String p)
boolean flag=false;
boolean s3 = true;
boolean s4 = false;
char ch[] = p.toCharArray();
for(int i=0,j=ch.length-1;i<j;i++,j--)
if(ch[i]==ch[j])
flag=true;
length++;
else
flag=false;
break;
if(flag==true)
System.out.println("Its a pallendrome");
return s3;
else
return s4;
public static void main(String s[])
boolean s2;
String a = new String("abac");
s2 = stringpallendrome(a);
System.out.println(s2);
我在各个网站上搜索了这个问题,发现它们很有用但无法理解。
http://articles.leetcode.com/2011/11/longest-palindromic-substring-part-i.html
我解决这个问题的领域是 java 中的代码,具有简单的蛮力解决方案,然后使用没有额外空间的 o(n2) 方法,就像现在一样。 http://www.geeksforgeeks.org/longest-palindromic-substring-set-2/
【问题讨论】:
这是你的代码;你有什么问题? 那么,您的问题是什么?这是一个很常见的问题。在此处发布问题之前先进行研究。查看此链接,例如programcreek.com/2013/12/… 所以你想知道的东西是否在一个单词中有一个回文,即使它不是完整的句子,对吧? @Micho 很抱歉给您带来不便。我编辑了代码。 @Skizo 是的,而且时间太长了。 【参考方案1】:这是一个多余的问题。你可以在这里找到答案。 Write a function that returns the longest palindrome in a given string
答案是
您可以使用 Manacher 算法在 准时!它的实现可以在here 和here 找到。 对于输入字符串 s = “HYTBCABADEFGHABCDEDCBAGHTFYW1234567887654321ZWETYGDE”。它发现 正确的输出是 1234567887654321。
【讨论】:
是的,问题是多余的。我没有要求 O(n) 中的任何 Manacher 算法。我只对了解 bruteForce 解决方案以及 O(n2) 方法感兴趣,没有额外的空间.前者我从多余的问题中理解,但后者仍然不理解。我在我的问题中提供了一个链接,来自我在 java 中理解的地方。【参考方案2】:见Manacher's algorithm.
它的时间复杂度是O(n)。
【讨论】:
这是 manacher 的,而不是 manchester 的。尊重发明者!!【参考方案3】:首先,检查一个字符串是否是回文可以通过:
static boolean isPalindrome(String p)
return p.equals(new StringBuilder(p).reverse().toString());
您的问题应该是:“如何有效地找到最长的回文?”。通常它是使用 Manacher 算法完成的。 Robert Sedgewick 和 Kevin Wayne 编写了很好的实现:
/******************************************************************************
* Compilation: javac Manacher.java
* Execution: java Manacher text
* Dependencies: StdOut.java
*
* Computes the longest palindromic substring in linear time
* using Manacher's algorithm.
*
* Credits: The code is lifted from the following excellent reference
* http://www.leetcode.com/2011/11/longest-palindromic-substring-part-ii.html
*
******************************************************************************/
public class Manacher
private int[] p; // p[i] = length of longest palindromic substring of t, centered at i
private String s; // original string
private char[] t; // transformed string
public Manacher(String s)
this.s = s;
preprocess();
p = new int[t.length];
int center = 0, right = 0;
for (int i = 1; i < t.length-1; i++)
int mirror = 2*center - i;
if (right > i)
p[i] = Math.min(right - i, p[mirror]);
// attempt to expand palindrome centered at i
while (t[i + (1 + p[i])] == t[i - (1 + p[i])])
p[i]++;
// if palindrome centered at i expands past right,
// adjust center based on expanded palindrome.
if (i + p[i] > right)
center = i;
right = i + p[i];
// Transform s into t.
// For example, if s = "abba", then t = "$#a#b#b#a#@"
// the # are interleaved to avoid even/odd-length palindromes uniformly
// $ and @ are prepended and appended to each end to avoid bounds checking
private void preprocess()
t = new char[s.length()*2 + 3];
t[0] = '$';
t[s.length()*2 + 2] = '@';
for (int i = 0; i < s.length(); i++)
t[2*i + 1] = '#';
t[2*i + 2] = s.charAt(i);
t[s.length()*2 + 1] = '#';
// longest palindromic substring
public String longestPalindromicSubstring()
int length = 0; // length of longest palindromic substring
int center = 0; // center of longest palindromic substring
for (int i = 1; i < p.length-1; i++)
if (p[i] > length)
length = p[i];
center = i;
return s.substring((center - 1 - length) / 2, (center - 1 + length) / 2);
// longest palindromic substring centered at index i/2
public String longestPalindromicSubstring(int i)
int length = p[i + 2];
int center = i + 2;
return s.substring((center - 1 - length) / 2, (center - 1 + length) / 2);
// test client
public static void main(String[] args)
String s = args[0];
Manacher manacher = new Manacher(s);
StdOut.println(manacher.longestPalindromicSubstring());
for (int i = 0; i < 2*s.length(); i++)
StdOut.println(i + ": " + manacher.longestPalindromicSubstring(i));
来源:http://algs4.cs.princeton.edu/53substring/Manacher.java.html
【讨论】:
【参考方案4】:这是一个查找最长“偶数”长度回文的伪代码示例,您可以为最长奇数长度的回文编写非常相似的代码。
enum State = INCREMENT, EXPAND, RESET // different states of the algorithm
int longestEvenPalindrome(String s)
int p1 = 0, p2 = 1, p3 = 1, longestPalindrome = 1;
State state = INCREMENT;
while(p2 < s.length)
switch(state)
case INCREMENT: // Incr. until matching chars
if(s[p1] == s[p2])
state = EXPAND;
p3 = p2 + 1;
else
p1++;
p2++;
break;
case EXPAND: // Expand until mismatching chars
if(p1 < 0 || s[p1] != s[p2])
state = RESET;
else
p1--; // Expand Left
p2++; // Expand Right
break;
case RESET:
longestPalindrome = Math.max(longestPalindrome, p2 - p1 - 2);
p2 = p3;
p1 = p3 - 1;
state = INCREMENT;
break;
return longestPalindrome;
【讨论】:
【参考方案5】:class LongPal
public static void main (String args[])
String k = new String("abcertmadamelkokokp"); //random string
boolean flag = false; //flag to check whether isPalindrome is true
int i, j , max_pal =0; //max_pal keeps account of length of the longest palindrome
String s ="";
String s1 = ""; //two strings
LongPal obj = new LongPal();
for (i=0;i<k.length();i++) //outer loop starts from index 0 of the string
for (j=k.length();j>i+1;j--) //inner loop starts from the end of the string
flag = obj.isPalindrome(k.substring(i,j)); //sending the substring to isPalindrome
if (flag)
s= k.substring(i,j); //storing the palindrome substring in s
if(s.length()>max_pal) // if the palindrome encountered has a length more than the previously encountered palindrome
max_pal = s.length(); //set max_pal to the length of the new palindrome
s1 = s; //store the new palindrome in s1
System.out.println("Longest Palindrome: "+ s1); //print the longest palindrome
public boolean isPalindrome(String s)
StringBuffer s1 = new StringBuffer(s); //copy String s to StringBuffer s1
StringBuffer s2 = new StringBuffer(s);//copy String s to StringBuffer s2
String rev=s2.reverse().toString(); //reverse s2 and convert it into string type and store the same in rev
if (s1.toString().equals(rev)) //convert s1 to string and compare with rev. You can't use .equals() for StringBuffer type.
return true;
else
return false;
【讨论】:
你能评论你的答案吗? @MartinPrikryl 做到了。 :)以上是关于找到最长的回文子串的主要内容,如果未能解决你的问题,请参考以下文章