LeetCode 5_Longest Palindromic Substring


LeetCode 5_Longest Palindromic Substring 

题目描述:

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. 也即:求字符串中最长回文子串!

回文是什么我就不多少了,可以百度下!

方法一:暴力法(O(n^3))

两层循环扫描字符串的所有子串,之后判断选出的字符子串是否是回文,若是则看其长度!代码如下:

class Solution {
public:
    string longestPalindrome(string s) 
    {
        // 暴力法O(n^3)
        int n = s.size();
		if (n == 0 || n == 1)
			return s;
		int maxLength = 1;
		int k1 = 0, k2 = 0;
		for (int i = 0; i < n; i++)
		{
			for (int j = i + 1; j < n; j++)
			{
				int k = 0;
				int sign = 0;
				while (k < (j - i + 1)/2 && s[i + k] == s[j - k])
					k++;
				if(k == (j - i + 1) / 2 )
				{
					sign = 1;
					if (j - i + 1 > maxLength)
					{
						maxLength = j - i + 1;
						k1 = i;
						k2 = j;
						if (maxLength == n - i)
						    return s.substr(k1,k2+1);
					}
				}
			}
		}
		return s.substr(k1,k2+1);
}
不用说,肯定超时!显然暴力法有很大的优化空间,在判断子串的时候肯定有很多重复的情况,可以用一个表记录已经判断的情况!

由于题目说可以假定字符串的长度不超过1000,所以建立一个table[1000][1000] 的bool表,初始化为false,如果某子串(假设 i 到 j )为回文,令table[ i ][ j ]为true,之后判断的时候先查表和更新表。代码如下:

class Solution {
public:
    string longestPalindrome(string s) 
    {
    		int n = s.length();
		if(n == 0 || n == 1)
		    return s;
		int maxLength = 1;
		int palindromBegin = 0;
		bool table[1000][1000] = {false};
		for(int i = 0; i < n; i++)
			table[i][i] = true;
		for (int i = 0; i < n; i++)
			if(s[i] == s[i + 1])
			{
			    table[i][i + 1] = true;
				maxLength = 2;
				palindromBegin = i;
			}
		for (int len = 3; len <= n ; len++)
		{
			for (int i = 0; i < n - len + 1; i++)
			{
				int j = i + len - 1;
				if (s[i] == s[j] && table[i + 1][j - 1] == true)
				{
				    table[i][j] = true;
					maxLength = len;
					palindromBegin = i;
				}
			}
		}
		return s.substr(palindromBegin, maxLength);
}

上面的方法时间复杂度为O(n^2),可以满足题目的要求。

其实还可以考虑回文的中心点,向两边扩展(回文的中心点可以是摸个字符,也可以是某两个字符的中间),代码如下:

string expandAroundCenter(string s, int c1, int c2) {
  int l = c1, r = c2;
  int n = s.length();
  while (l >= 0 && r <= n-1 && s[l] == s[r]) {
    l--;
    r++;
  }
  return s.substr(l+1, r-l-1);
}
class Solution {
public:
    string longestPalindrome(string s) 
    {
      int n = s.length();
      if (n == 0) return "";
      string longest = s.substr(0, 1);  // a single char itself is a palindrome
      for (int i = 0; i < n-1; i++) {
        string p1 = expandAroundCenter(s, i, i);
        if (p1.length() > longest.length())
          longest = p1;
     
        string p2 = expandAroundCenter(s, i, i+1);
        if (p2.length() > longest.length())
          longest = p2;
      }
      return longest;
    }
};
代码的复杂度为O(n^2)。还有一种说复杂度为O(n)的方法,不过我没去看,有兴趣的可以看下: http://www.cnblogs.com/bitzhuwei/p/Longest-Palindromic-Substring-Part-II.html。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值