LeetCode 最长回文子串(C++)

暴力解决(超时):

//是否是回文串
bool is(string str)
{
	if (str.length() == 1)
		return true;
	else if (str.length() == 2)
	{
		if (str[0] == str[1])
			return true;
		else
			return false;
	}
	else if (str[0] == str[str.length() - 1])
		return is(str.substr(1, str.length() - 2));
	else
		return false;
}
string longestPalindrome(string s) {
	int maxlen = 0;
	int start = 0;//回文子串开始下标
	int end = 1;//结束下标
	//遍历所有子串
	for (int i = 0; i < s.length(); i++)
	{
		for (int j = i; j < s.length(); j++)
		{
			if (is(s.substr(i, j - i + 1)))//子串为回文串
			{
				if (j - i + 1 > maxlen)//是否最大回文串
					{
						maxlen = j - i + 1;
						start = i;
						end = j;
					}
			}
		}
	}
	return s.substr(start, end - start + 1);
}

把串变成奇数长度的串(参照网上方法)

如:aabbaa 变成 #a#a#b#b#a#a#(2*length+1,所以是奇数长度的串)

然后就可以从中间向两边扩展回文串(如果不是奇数长度的串的话,如aabbaa就没法从中间扩展)

class Solution {
public:
    bool is(string str)
    {
	    if (str.length() == 1)
    		return true;
    	else if (str.length() == 2)
    	{
    		if (str[0] == str[1])
    			return true;
    		else
    			return false;
    	}
    	else if (str[0] == str[str.length() - 1])
	    	return is(str.substr(1, str.length() - 2));
	    else
	    	return false;
    }
    string longestPalindrome(string s) {
	    string str = s + s + 's';//把str长度设为2*s.length()+1
	    string result;//结果
        string temp;//带#的中间结果
	    int left = 0;//往左扩展
	    int right = 0;//往右扩展
	    int start = 0;//中间结果开始下标
	    int end = 0;//中间结果结束下标
	    for (size_t i = 0; i < str.length(); i++)//处理str
	    {
	    	if (0 == i % 2)
	    		str[i] = '#';
	    	else
		    	str[i] = s[i / 2];
	    }
	    for (size_t i = 0; i < str.length(); ++i)
	    {
	    	left = i - 1;
	    	right = i + 1;
	    	while (left >= 0 && right < str.length() 
                   && str[left] == str[right])
	    	{
		    	--left;
		    	++right;
		    }
		    if (end-start <= right-left-2)//新的更长的回文串
		    {
		    	start = ++left;
		    	end = --right;
		    }
	    }
	    temp = str.substr(start, end - start + 1);
	    result = temp.substr(0, temp.length() / 2);
	    for (int i = 0; i < temp.length(); i++)//由temp得到result
	    {
	    	if (0 == i % 2)
	    		continue;
	    	else
		    	result[i / 2] = temp[i];
	    }
	    return result;
    }
};

 

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值