5、Longest Palindromic Substring

本文探讨了三种方法来解决寻找给定字符串中最长回文子串的问题:中心扩散法、Manacher算法以及字符串预处理技巧。详细解释了每种方法的原理与实现步骤,旨在为读者提供不同角度的解决方案。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

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.

String

方法1:

class Solution {
public:
    string longestPalindrome(string s) {
        //此题有三种解决方法:1、中心扩散法 2、Manacher算法 3、
        //方法1和方法2需要先对字符串进行变换
        //中心扩散法
        char str[2010];
        int index = 0;
        int len = s.size();
        str[index++] = '&';
        for (int i = 0; i < len; ++i)
        {
            str[index++] = '#';
            str[index++] = s[i];
        }
        str[index++] = '#';
        str[index] = '$';
        int maxLength = 0, place1 = 2;
        for (int i = 1; i < index; ++i)
        {
            int j2 = i + 1, j1 = i - 1;
            while (str[j1] == str[j2])
            {
                ++j2;
                --j1;
            }
            int tempLength = j2 - j1 - 1;
            if (maxLength < tempLength)
            {
                maxLength = tempLength;
                place1 = j1 + 2;
            }
        }
        return s.substr(place1 / 2 - 1, maxLength / 2);
    }
};

方法2:

string longestPalindrome(string s) {
        //此题有三种解决方法:1、中心扩散法 2、Manacher算法 3、
        //方法1和方法2需要先对字符串进行变换
        char str[2010];
        int index = 0;
        int len = s.size();
        str[index++] = '&';
        for (int i = 0; i < len; ++i)
        {
            str[index++] = '#';
            str[index++] = s[i];
        }
        str[index++] = '#';
        str[index] = '$';
        //Manacher算法去除了中心扩散中的部分冗余计算,但是需要空间开销来记录每个中心点向外扩散的半径
        int id[2010];
        id[0] = 1;
        int maxIndex = 0;
        int maxRadix = 1;
        int maxLength = 1, place1 = 2;
        for (int i = 1; i < index; ++i)
        {
            id[i] = 1;
            if (i < maxRadix)
            {
                //找到以maxIndex为中心的对称的值
                int j = 2 * maxIndex - i;
                if (id[j] + i < maxRadix)
                    id[i] = id[j];
                else
                    id[i] = maxRadix - i;
            }
            while (str[i+id[i]] == str[i-id[i]])
                ++id[i];
            if (id[i] + i > maxRadix)
            {
                maxRadix = id[i] + i;
                maxIndex = i;
            }
            if (id[i] > maxLength)
            {
                maxLength = id[i];
                place1 = i - id[i] + 2;
            }
        }
        return s.substr(place1 / 2 - 1, maxLength - 1);
    }

方法3:

 string longestPalindrome(string s) {
        //方法3:中心扩散法的变种,此种方法不需要对字符串做预处理
        int len = s.size();
        int i = 0;
        int maxLength = 0, place = 0;
        while (i < len)
        {
            int start = i, end = i + 1;
            while (end < len && s[start] == s[end])
                ++end;
            i = end;
            --start;
            while (start >= 0 && end < len && s[start] == s[end])
            {
                --start;
                ++end;
            }
            int tmpLength = end - start - 1;
            if (maxLength < tmpLength)
            {
                maxLength = tmpLength;
                place = start + 1;
            }
        }
        return s.substr(place, maxLength);
        
    }


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值