zoukankan      html  css  js  c++  java
  • 【leetcode 5. 最长回文子串】解题报告

    方法一:中心扩展算法

    解题思路:从左到右每一个字符都作为中心轴,然后逐渐往两边扩展,只要发现有不相等的字符,则确定了以该字符为轴的最长回文串,但需要考虑长度为奇数和偶数的不同情况的处理(长度为偶数时轴心为中间两个数的中心,长度为奇数时轴心为中间那个数)

    算法时间复杂度:$O(n^{2})$

        string longestPalindrome(string s) {        
            int idx = 0, maxL = 0;
            for (int i = 0; i < s.size(); ++i)  // i为轴的位置,j为回文串半径
            {
                for (int j = 0; i - j >= 0 && i + j < s.size(); ++j)    // 奇数
                {
                    if (s[i - j] != s[i + j])
                        break;
                    if (2 * j + 1 > maxL)
                    {
                        maxL = 2 * j + 1;
                        idx = i - j;
                    }
                }
                for (int j = 0; i - j >= 0 && i + j + 1 < s.size(); ++j)    // 偶数
                {
                    if (s[i-j]!=s[i+j+1])
                        break;
                    if (2 * j + 2 > maxL)
                    {
                        maxL = 2 * j + 2;
                        idx = i - j;
                    }
                }
            }
            return s.substr(idx, maxL);
        }

    方法二:manacher(马拉车法)

    解题思路:详见P3805 【模板】manacher算法

    算法时间复杂度为:$O(n)$

        int pos[2005],p[2005];
        string longestPalindrome(string s) {        
            /* 填充字符,统一为奇数串 */
            string s_new="~";
            for (int i=0,k=1;i<s.size();++i)
            {
                s_new+="#";
                s_new+=s[i];
                pos[k++]=i; // 记录新字串与原始字串的位置关系
                pos[k++]=i;
            }
            s_new+="#";
            
            /* manacher */
            int m=0,r=0,maxL=0,idx=0;
            for (int i=1;i<s_new.size();++i)
            {
                // 获取已知的最小回文半径
                if (i<r)
                    p[i]=min(p[2*m-i],r-i);
                else
                    p[i]=1;
                // 暴力拓展左右两侧
                while (s_new[i-p[i]]==s_new[i+p[i]])
                    p[i]++;
                // 新的回文半径比较大,则更新
                if (r-i<p[i])
                {
                    m=i;
                    r=i+p[i];
                }
                // 更新回文长度(原始字串的回文长度为新字串回文半径-1)
                if (p[i]-1>maxL)
                {
                    maxL=p[i]-1;
                    idx=pos[i]-maxL/2;  // 更新原始回文字串的起始位置
                }
            }
            return s.substr(idx,maxL);
        }
  • 相关阅读:
    网站收录(2)-财经网站
    网络爬虫(13)-Scrapy持久化存储
    网络爬虫(12)-Scrapy框架Post请求发送
    Excel常用函数
    VBA基础
    网站收录(1)-行业研究
    网络爬虫(11)-Scrapy分布式
    网络爬虫(10)-进程、线程
    log
    关于camera 智障的问题
  • 原文地址:https://www.cnblogs.com/brianyi/p/10812527.html
Copyright © 2011-2022 走看看