想到上月28号去百度笔试,遇到了一道题:已知一个N(N很大)长的字符串,求最长的回文子串。
看了一些博客,有很多种方法实现,我选其中的两种方法:
1.暴力搜索法。即不使用技巧,穷举所有可能。时间复杂度为O(n^3)(时间上最长,不推荐使用),空间复杂度为O(1)。
2.由中心向两边扩展法。时间复杂度为O(n^2),空间复杂度为O(1),稍好,并且易于理解,推荐使用。
由于没有限制语言,我分别用C++和Java实现,如下:
C++:1.暴力搜索法:
- #include<string>
- #include<iostream>
- using namespace std;
- string IsPalindrome(string str){
- if(str==""){
- return "";
- }
- int n=str.length();
- int maxLength=-1;
- int maxIndex=0;
- for(int i=0;i<n;i++){
- for(int j=i;j<n;j++){
- int start=i;
- int end=j;
- bool flag=true;
- while(start<=end){
- if(str[start]!=str[end]){
- flag=false;
- break;
- }
- start++;
- end--;
- }
- int tmpLength=j-i+1;
- if(flag&&tmpLength>maxLength){
- maxLength=tmpLength;
- maxIndex=i;
- }
- }
- }
- return str.substr(maxIndex,maxLength);
- }
- int main(){
- string str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
- string s=IsPalindrome(str);
- cout<<s<<endl;
- return 0;
- }
#include<string>
#include<iostream>
using namespace std;
string IsPalindrome(string str){
if(str==""){
return "";
}
int n=str.length();
int maxLength=-1;
int maxIndex=0;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
int start=i;
int end=j;
bool flag=true;
while(start<=end){
if(str[start]!=str[end]){
flag=false;
break;
}
start++;
end--;
}
int tmpLength=j-i+1;
if(flag&&tmpLength>maxLength){
maxLength=tmpLength;
maxIndex=i;
}
}
}
return str.substr(maxIndex,maxLength);
}
int main(){
string str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
string s=IsPalindrome(str);
cout<<s<<endl;
return 0;
}
2.由中心向两边扩展法:
- #include<string>
- #include<iostream>
- using namespace std;
- string getString(string str,int l,int r){
- int n=str.length();
- while(l>=0&&r<=n-1&&str[l]==str[r]){
- l--;
- r++;
- }
- return str.substr(l+1,r-l-1);
- }
- string IsPalindrome(string str){
- int n=str.length();
- if(str==""){
- return "";
- }
- string longest=str.substr(0,1);
- for(int i=0;i<n-1;i++){
- string p1=getString(str,i,i);
- if(p1.length()>longest.length()){
- longest=p1;
- }
- string p2=getString(str,i,i+1);
- if(p2.length()>longest.length()){
- longest=p2;
- }
- }
- return longest;
- }
- int main(){
- string str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
- string s=IsPalindrome(str);
- cout<<s<<endl;
- return 0;
- }
#include<string>
#include<iostream>
using namespace std;
string getString(string str,int l,int r){
int n=str.length();
while(l>=0&&r<=n-1&&str[l]==str[r]){
l--;
r++;
}
return str.substr(l+1,r-l-1);
}
string IsPalindrome(string str){
int n=str.length();
if(str==""){
return "";
}
string longest=str.substr(0,1);
for(int i=0;i<n-1;i++){
string p1=getString(str,i,i);
if(p1.length()>longest.length()){
longest=p1;
}
string p2=getString(str,i,i+1);
if(p2.length()>longest.length()){
longest=p2;
}
}
return longest;
}
int main(){
string str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
string s=IsPalindrome(str);
cout<<s<<endl;
return 0;
}
Java:1.暴力搜索法:
- public class Palindrome2 {
- private static String longestPalindrome(String str){
- if(str==""){
- return "";
- }
- int n=str.length();
- int maxLength=-1;
- int beginIndex=0;
- int endIndex=0;
- for(int i=0;i<n;i++){
- for(int j=i;j<n;j++){
- int start=i;
- int end=j;
- boolean flag=true;
- while(start<=end){
- if(str.charAt(start)!=str.charAt(end)){
- flag=false;
- break;
- }
- start++;
- end--;
- }
- int tmpLength=j-i+1;
- if(flag&&tmpLength>maxLength){
- maxLength=tmpLength;
- beginIndex=i;
- endIndex=j+1;
- }
- }
- }
- return str.substring(beginIndex,endIndex);
- }
- public static void main(String[] args){
- String str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
- String s=longestPalindrome(str);
- System.out.println(s);
- }
- }
public class Palindrome2 {
private static String longestPalindrome(String str){
if(str==""){
return "";
}
int n=str.length();
int maxLength=-1;
int beginIndex=0;
int endIndex=0;
for(int i=0;i<n;i++){
for(int j=i;j<n;j++){
int start=i;
int end=j;
boolean flag=true;
while(start<=end){
if(str.charAt(start)!=str.charAt(end)){
flag=false;
break;
}
start++;
end--;
}
int tmpLength=j-i+1;
if(flag&&tmpLength>maxLength){
maxLength=tmpLength;
beginIndex=i;
endIndex=j+1;
}
}
}
return str.substring(beginIndex,endIndex);
}
public static void main(String[] args){
String str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
String s=longestPalindrome(str);
System.out.println(s);
}
}
2.由中心向两边扩展法:
- public class Palindrome {
- private static String longestPalindrome(String str){
- int n=str.length();
- if(str==""){
- return "";
- }
- String longest=str.substring(0, 1);
- for(int i=0;i<n-1;i++){
- String p1=expandAroundCenter(str,i,i);
- if(p1.length()>longest.length()){
- longest=p1;
- }
- String p2=expandAroundCenter(str,i,i+1);
- if(p2.length()>longest.length()){
- longest=p2;
- }
- }
- return longest;
- }
- private static String expandAroundCenter(String str,int l,int r){
- int n=str.length();
- while(l>=0&&r<=n-1&&str.charAt(l)==str.charAt(r)){
- l--;
- r++;
- }
- /**
- * 这里要注意,c++中的str.substr(beginIndex,length)的后一个参数是从beginIndex开始的长度,
- * 而java中的str.substring(beginIndex,endIndex)的后一个参数是一个下标,应不小于beginIndex,
- * 并且在获取的字符串中,不包括该下标,
- */
- return str.substring(l+1, r);
- }
- public static void main(String[] args){
- String str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
- String s=longestPalindrome(str);
- System.out.println(s);
- }
- }
public class Palindrome {
private static String longestPalindrome(String str){
int n=str.length();
if(str==""){
return "";
}
String longest=str.substring(0, 1);
for(int i=0;i<n-1;i++){
String p1=expandAroundCenter(str,i,i);
if(p1.length()>longest.length()){
longest=p1;
}
String p2=expandAroundCenter(str,i,i+1);
if(p2.length()>longest.length()){
longest=p2;
}
}
return longest;
}
private static String expandAroundCenter(String str,int l,int r){
int n=str.length();
while(l>=0&&r<=n-1&&str.charAt(l)==str.charAt(r)){
l--;
r++;
}
/**
* 这里要注意,c++中的str.substr(beginIndex,length)的后一个参数是从beginIndex开始的长度,
* 而java中的str.substring(beginIndex,endIndex)的后一个参数是一个下标,应不小于beginIndex,
* 并且在获取的字符串中,不包括该下标,
*/
return str.substring(l+1, r);
}
public static void main(String[] args){
String str="djdslkAABCDEAfjdl1234321skjflkdsjfkldsababasdlkfjsdwieowowwpw";
String s=longestPalindrome(str);
System.out.println(s);
}
}
以上输出结果均为:dsjfkldsababasdlkfjsd.