• (算法)最长回文子串


    题目:

    求一个字符串的最长回文子串

    思路:

    1、暴力枚举

    最容易想到的就是暴力破解,列举每一个子串,然后根据回文的定义判断是不是回文,找到最长的那个。

    求每一个子串的时间复杂度为O(N^2),判断子串是不是回文的时间复杂度为O(N),所以时间复杂度为O(N^3)。

    2、动态规划

    回文字符串的子串也是回文,比如P[i,j](表示以i开始以j结束的子串)是回文字符串,那么P[i+1,j-1]也是回文字符串。这样最长回文子串就能分解成一系列子问题了。

    这样需要额外的空间是O(N^2),时间复杂度也是O(N^2)。

    状态转移方程:

    当str[i]=str[j] dp[i][j]=dp[i+1][j-1] 

    当str[i]!=str[j] dp[i][j]=0

    初始状态:

    dp[i][i]=1

    dp[i][i+1]=1 if str[i]=str[i+1]

    3、中心扩展

    中心扩展就是把给定的字符串的每一个字符当做中心,向两边扩展,这样来找最长的子回文串。时间复杂度为O(N^2)。

    但是要考虑两种情况:

    如aba,这样长度为奇数。

    如abba,这样长度为偶数。

    4、Manacher法

    待续

    代码:

    #include<iostream>
    using namespace std;
    
    // brute force
    string findLongestPalindrome_1(string &str){
    	int length=str.size();
    	int maxLength=0;
    	int start;
    
    	for(int i=0;i<length;i++){
    		for(int j=i+1;j<length;j++){
    			int left,right;
    			for(left=i,right=j;left<right;left++,right--){
    				if(str[left]!=str[right])
    					break;
    			}
    			if(left>=right && (j-i)>maxLength){
    				maxLength=j-i+1;
    				start=i;
    			}
    		}
    	}
    
    	if(maxLength>0)
    		return str.substr(start,maxLength);
    	return NULL;
    }
    
    
    // dynamic programming
    string findLongestPalindrome_2(string &str){
    	const int length=str.size();
    	int maxLength=1;
    	int start;
    
    	bool dp[length][length];
    
    	for(int i=0;i<length;i++)
    		for(int j=0;j<length;j++)
    			dp[i][j]=false;
    
    	for(int i=0;i<length;i++){
    		dp[i][i]=true;
    		if(i<length-1 && str[i]==str[i+1]){
    			dp[i][i+1]=true;
    			start=i;
    			maxLength=2;
    		}
    	}
    
    	for(int len=3;len<=length;len++){
    		for(int i=0;i<=length-len;i++){
    			int j=i+len-1;
    			if(dp[i+1][j-1] && str[i]==str[j]){
    				dp[i][j]=true;
    				start=i;
    				maxLength=len;
    			}
    		}
    	}
    
    	if(maxLength>=2)
    		return str.substr(start,maxLength);
    	return NULL;
    }
    
    // pivot expand
    string findLongestPalindrome_3(string &str){
    	const int length=str.size();
    	int maxLength=1;
    	int start;
    
    	for(int i=0;i<length;i++){
    		int left=i-1;
    		int right=i+1;
    		while(left>=0 && right<=length-1 && str[left]==str[right]){
    			if(right-left+1>maxLength){
    				start=left;
    				maxLength=right-left+1;
    			}
    			left--;
    			right++;
    		}
    	}
    
    	for(int i=0;i<length;i++){
    		int left=i;
    		int right=i+1;
    		while(left>=0 && right<=length-1 && str[left]==str[right]){
    			if(right-left+1>maxLength){
    				start=left;
    				maxLength=right-left+1;
    			}
    			left--;
    			right++;
    		}
    	}
    
    	if(maxLength>0)
    		return str.substr(start,maxLength);
    	return NULL;
    }
    
    
    int main(){
    	string str="ababcddcbbd";
    	cout<<findLongestPalindrome_1(str)<<endl;
    	cout<<findLongestPalindrome_2(str)<<endl;
    	cout<<findLongestPalindrome_3(str)<<endl;
    	return 0;
    }
    

      

  • 相关阅读:
    AIMS 2013中的性能报告工具不能运行的解决办法
    读懂AIMS 2013中的性能分析报告
    在线研讨会网络视频讲座 方案设计利器Autodesk Infrastructure Modeler 2013
    Using New Profiling API to Analyze Performance of AIMS 2013
    Map 3D 2013 新功能和新API WebCast视频下载
    为Autodesk Infrastructure Map Server(AIMS) Mobile Viewer创建自定义控件
    ADN新开了云计算Cloud和移动计算Mobile相关技术的博客
    JavaScript修改css样式style
    文本编辑神器awk
    jquery 开发总结1
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4746351.html
Copyright © 2020-2023  润新知