求字符串中最长回文


Given a string S, find the longest palindromic substring in S. You may assume that the maximum length of S is 1000, and there exists one unique longest palindromic substring.

    Hide Tags
      String

    Solutions:

    1)将sreverse得到revS,然后求s和revS的最长公共字串(不是最长公共子序列)。复杂度为O(N^2),空间也是。但还是总提示超时。在本机上测试500长度用例用时161ms。

    class Solution {
    private:	
    	string lcstr(string str1, string str2) {
    		string ret;
    		int size=str1.size();
    		int i=0, j=0;
    		int lowLoc=0, highLoc=0;
    	//	vector<vector<int> > c(size+1, vector<int>(size+1));
    		int **c=new int*[size+1];
    		for(i=0; i<=size; ++i) {
    			c[i]=new int[size+1];
    		}
    		for(i=0; i<=str1.size(); ++i) {
    			c[i][0] = 0;
    		} 
    		for(j=0; j<=str2.size(); ++j) {
    			c[0][j] = 0;
    		}
    		int maxLength=0;
    		for(i=1; i<=str1.size(); ++i) {
    			for(j=1; j<=str2.size(); ++j) {
    				if(str1[i-1] == str2[j-1]) {
    					c[i][j] = c[i-1][j-1]+1;
    				}
    				else {					
    					c[i][j] = 0;
    				}
    				if(c[i][j]>maxLength) {
    					maxLength=c[i][j];
    					lowLoc=i;
    					highLoc=j;
    				}
    			}
    		}
    		for(i=0; i<=size; ++i) {
    			delete [] c[i];
    			c[i]=NULL;
    		}
    		delete []c;
    		return str1.substr(lowLoc-maxLength, maxLength);
    	}
    public:
    	string longestPalindrome(string s) {
    		int size=s.size();
    //		vector<vector<int> > c(size+1, vector<int>(size+1));
    //		vector<vector<int> > b(size+1, vector<int>(size+1));
    		string revS;
    		for(int i=s.size()-1; i>=0; --i) {
    			revS+=s[i];
    		}
    		return lcstr(s, revS);		 
    	}
    };

    2)从某一个字符向两侧对称地扩展,直到不能对称为止。但要注意像“aa”这样的,所以每到一个字符要分别做奇偶扩展。时间复杂度为O(N^2)。

    class Solution {
    public:
    	string longExpand(string s, int low, int high) {
    		//int l=low, h=high;
    		while(low >= 0 && high<s.size() && s[low]==s[high]) {
    			--low;
    			++high;
    		}
    	//	string ret;
    		return s.substr(low+1, high-low-1);
    	//	return ret;
    	}
    	string longestPalindrome(string s) {
    		string ret;
    		string odd, even;
    		for(int i=0; i<s.size(); ++i) {
    			odd=longExpand(s, i, i);
    			even=longExpand(s, i, i+1);
    			if(odd.size() > ret.size()) {
    				ret=odd;
    			}
    			if(even.size() > ret.size()) {
    				ret=even;
    			}
    		}
    		return ret;
    	}
    };

    Manacher’s Algorithm,O(n)的算法(看不懂)

    class Solution{
    public:
    	string longestPalindrome(string s) {
    		string T = preProcess(s);
    		int n = T.length();
    		int *P = new int[n];
    		int C = 0, R = 0;
    		int i=0;
    		for (i = 1; i < n-1; i++) {
    			int i_mirror = 2*C-i; // equals to i' = C - (i-C)
    			
    			P[i] = (R > i) ? min(R-i, P[i_mirror]) : 0;
    			
    			// 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 expand past R,
    			// adjust center based on expanded palindrome.
    			if (i + P[i] > R) {
    				C = i;
    				R = i + P[i];
    			}
    		}
    		
    		// Find the maximum element in P.
    		int maxLen = 0;
    		int centerIndex = 0;
    		for (i = 1; i < n-1; i++) {
    			if (P[i] > maxLen) {
    				maxLen = P[i];
    				centerIndex = i;
    			}
    		}
    		delete[] P;
    		
    		return s.substr((centerIndex - 1 - maxLen)/2, maxLen);
    	}
    private:
    	int min(int a, int b) {
    		return a<b?a:b;
    	}
    	string preProcess(string s) {
    		int n = s.length();
    		if (n == 0) return "^$";
    		string ret = "^";
    		for (int i = 0; i < n; i++)
    			ret += "#" + s.substr(i, 1);
    		
    		ret += "#$";
    		return ret;
    	}
    };


    评论
    添加红包

    请填写红包祝福语或标题

    红包个数最小为10个

    红包金额最低5元

    当前余额3.43前往充值 >
    需支付:10.00
    成就一亿技术人!
    领取后你会自动成为博主和红包主的粉丝 规则
    hope_wisdom
    发出的红包
    实付
    使用余额支付
    点击重新获取
    扫码支付
    钱包余额 0

    抵扣说明:

    1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
    2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

    余额充值