• (算法)最长回文子串


    题目:

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

    思路:

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

      

  • 相关阅读:
    在VS2008中使用WSE 3.0【转】
    .Net调用Java端带有WS-Security支持的Web Service各方案实战【转】
    Java与WCF交互(一):Java客户端调用WCF服务 【转】
    Java与WCF交互(二):WCF客户端调用Java web service【转】
    c#调用带有安全认证的java webservice
    利用Web Services开发分布式应用
    注册dll文件
    Oracle:"ORA-00942: 表或视图不存在"
    sql_server角色成员身份权限
    10013: 以一种访问权限不允许的方式做了一个访问套接字的尝试【WCF异常】
  • 原文地址:https://www.cnblogs.com/AndyJee/p/4746351.html
Copyright © 2020-2023  润新知