【Leetcode】之Longest Palindromic Substring

本文探讨了如何通过遍历字符串并寻找对称中心来高效地找到最长回文子串,提供了时间复杂度为O(n^2)到O(n)的解决方案,并详细解释了算法背后的逻辑。

摘要生成于 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.

我的解题思路:
题目要求的是最长回文子串,关键字是回文 子串。之前遇到过求解最长不重复子串的问题,这两个问题还是有一定相似性的。所以一开始是想借鉴《最长不重复子串的问题》的思路,但是想了一会之后发现这两个问题有着一个本质的区别:就是本题的子问题不重复,从每个字符开始寻找回文子串都是一个独立的问题,无法应用到之前遍历的结果。因此,本题不适合直接照搬《最长不重复子串的问题》的思路。

再分析回文子串的性质,发现回文子串都是中心对称的,一个回文子串的对称中心要么是两个相等的字符,要么是一个独立的字符。如“bccb”中心是cc ‘dbd’中心是b。
于是就有这样的想法:能不能对原字符串进行遍历,寻找对称中心。每次寻找到一个对称中心之后,再从中心向两边扩展,记录该中心扩展得到的最长回文子串的长度和起始位置。这样对整个字符串遍历完之后,就可以得到所有子串中最长的回文子串。编写程序如下:

class Solution {
public:
    string longestPalindrome(string s) {

  int len=s.length();
        int max_len=0;
        int max_idx=0;
        int curr_len=0;
        int pt2=len-1;int pt1=len-2;
        int tmp1=0;int tmp2=0;
        if(len<=1)
            return s;
        while((pt1>=0)) //寻找对称中心是两个相等字符的回文子串
            {
                if(s[pt1]==s[pt2]) //找到一个对称中心
                {
                    tmp1=pt1;
                    tmp2=pt2;
                    while(tmp1>=0&&tmp2<=len-1) //从中心向两边进行扩展
                    {
                        if(s[tmp1]==s[tmp2])
                        {
                         curr_len=tmp2-tmp1+1;
                        tmp1--;
                        tmp2++;
                        }
                        else
                            break;
                    }
                    if(curr_len>max_len) //记录当前最长的回文子串的长度和下标
                    {
                        max_len=curr_len;
                        max_idx=tmp1+1;
                    }
                    pt1--;
                    pt2--;

                }
                else
                {
                pt1--;
                pt2--;
                }
            }
          pt2=len-1; pt1=len-3;
          tmp1=0; tmp2=0;
          while((pt1>=0))   //寻找对称中心为单个字符的回文子串
            {
                if(s[pt1]==s[pt2])
                {
                    tmp1=pt1;
                    tmp2=pt2;
                    while(tmp1>=0&&tmp2<=len-1)
                    {
                        if(s[tmp1]==s[tmp2])
                        {
                         curr_len=tmp2-tmp1+1;
                        tmp1--;
                        tmp2++;
                        }
                        else
                            break;
                    }
                    if(curr_len>max_len)
                    {
                        max_len=curr_len;
                        max_idx=tmp1+1;
                    }
                    pt1--;
                    pt2--;

                }
                else
                {
                pt1--;
                pt2--;
                }
            }

            string res(s,max_idx,max_len);
            return res;
    }
};

编写完程序之后,提交,本来还担心时间复杂度不符合要求,没想到一次就accept了。分析下我的程序,最坏的复杂度应该是2*O(n^2)=O(n^2),最好的情况应该能达到O(n)。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值