2014百度校园招聘笔试——求一个字符串的最长回文子串

想到上月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;
}
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;
}

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);
	}
}

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);
	}
}

以上输出结果均为:dsjfkldsababasdlkfjsd.

参考:http://www.cnblogs.com/ZJUKasuosuo/archive/2012/07/19/2599636.html

猜你喜欢

转载自blog.csdn.net/zhk7894613/article/details/12220501