力扣刷题五:最长回文子串(python3)

回文子串
第一个想法就是暴力解题,遍历所有子串,找出最大的,毫无疑问,双重循环很耗时:

class Solution:
    def longestPalindrome(self, s: str) -> str:
        data = []
        maxstring = []
    
        for i in range(len(s)):
            for j in range(i+1,len(s)+1):
                data = s[i:j]
                if data == data[::-1]:
                    if len(data) > len(maxstring):
                        maxstring = data
        return maxstring

改进,减少循环次数,7248 ms,15mb:

class Solution:
    def longestPalindrome(self, s: str) -> str:
        max_s = 0
        m_s = []
        for i in range(len(s)):
            for j in range(len(s)):
                if j>i and s[i]==s[j]:
                    if s[i:j+1] == s[i:j+1][::-1]:
                        if j-i+1 > max_s:
                          max_s = j - i + 1
                          m_s = s[i:j+1]
 
        if not m_s:       
            m_s = s[0]
        return m_s

第二个方法就是动态规划法,牺牲空间来换时间请添加图片描述

class Solution {
public:
    string longestPalindrome(string s) {
        string ans=s.substr(0,1);
        int maxLen=1;
        auto len=s.size();
        vector<vector<bool>> dp(len,vector<bool>(len,0));
        for(int i=0;i!=len;++i)dp[i][i]=1;//初始化边界条件,即对角线
       //第一层遍历边界,设置子字符串范围,范围为0-j
        for(int j=1;j!=len;++j){
            //第二层遍历遍历子字符串内部。即0到j区间内的所有字符串,可理解为孙字符串
            for(int i=0;i!=j;++i){
                if(s[i]!=s[j])dp[i][j]=0;//如果子字符串边界不相等,那么这个子字符串必然不是回文
                //字符串边界相等的情况下,其长度小于等于3的情况,那么必然是回文。如aba,bb。这个点也是最难想到的
                else if(j-i<3)dp[i][j]=1;
                //字符串边界相等的情况下,其是否为回文取决于i+1到j-1范围内的字符串是否为回文
                else dp[i][j]=dp[i+1][j-1];
                //如果当前字符串的长度比之前的最大长度还长,那么覆盖
                if(dp[i][j]&&maxLen<j-i+1)maxLen=j-i+1,ans=s.substr(i,maxLen);
            }
        }
        return ans;
    }
};


第三个方法就是中心扩散法,要注意一点,中心是一个字母还是两个字母

class Solution {
public:
    string longestPalindrome(string s) {
        int maxLen=1;
        string ans=s.substr(0,1);
        //中心扩散法,遍历字符串s,判断每个位置可构成的最大回文串
        for(int i=0;i<s.size()-1;++i){
            int start=i,end=i;
            //情况1:中心只有一个字母的情况。如aba
            for(int l=i-1,r=i+1;l!=-1&&r!=s.size();--l,++r){
               if(s[l]==s[r]){start=l;end=r;}//如果一直符合回文要求,继续往两边扩散
               else break;//一不符合要求马上终止
            }
            //如果当前字符串的长度比之前的最大长度还长,那么覆盖
            if(end-start+1>maxLen)maxLen=end-start+1,ans=s.substr(start,maxLen);
            //情况2:中心只有两个字母的情况。如abba
            if(i!=s.size()-1&&s[i]==s[i+1]){
                for(int l=i,r=i+1;l!=-1&&r!=s.size();--l,++r){
                    if(s[l]==s[r]){start=l;end=r;}//如果一直符合回文要求,继续往两边扩散
                    else break;//一不符合要求马上终止
                }
            }
            //如果当前字符串的长度比之前的最大长度还长,那么覆盖
            if(end-start+1>maxLen)maxLen=end-start+1,ans=s.substr(start,maxLen);
        }
        return ans;
    }
};


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值