一天一道LeetCode系列

(一)题目

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.

题意:求一个字符串的最长回文字串。

(二)解题

1.中心扩展法

看到这个题首先想到的就是中心扩展法,遍历每一个字符,然后以该字符为中心向四周扩展,这种方法的时间复杂度为O(N^2),但是需要注意的是,奇数和偶数回文字符串需要区别对待,如aba和abba都是回文字符串。

class Solution {
public:
    string longestPalindrome(string s) {
        int max1=0;//奇数最长子串
        int max2=0;//偶数最长子串
        int idx1=0;//奇数最长子串的中心字符
        int idx2=0;//偶数最长子串的中心字符
        string result;
        for(int i = 0 ; i < s.length() ; ++i)
        {
            int j = i;
            int z = i;
            int count1=0;
            int count2=0;
            //计算奇数最长回文字符串
            while((++z<s.length()) && (--j>=0) && (s[z] == s[j]))
            {
                count1+=2;
                if(count1 > max1)
                {
                    max1=count1;
                    idx1 = i;
                }
            }
            //计算偶数最长回文字符串
            j = i;
            z = i+1;
            while((z<s.length()) && (j>=0) &&(s[z] == s[j]))
            {
                count2+=2;
                if(count2 > max2)
                {
                    max2=count2;
                    idx2 = i;
                }
                z++;
                j--;
            }
        }
        if(max1+1>max2) result = s.substr(idx1-max1/2,max1+1);
        else result = s.substr(idx2-max2/2+1,max2);
        return result;
    }
};

2.中心扩展法的优化

区分奇数和偶数显得程序比较臃肿,我们可以利用“改造“字符串来避免这种情况。如aba改成#a#b#a#,abba改成#a#b#b#a,这样就不用区分奇偶了。

class Solution {
public:
    string longestPalindrome(string s) {
        int max=0;
        int idx=0;
        string temp[2005];
        //改造字符串
        int j = 0;
        for(int i = 0; i < s.length() ; ++i)
        {
            temp[j++] = '#';
            temp[j++] = s[i];
        }
        temp[j++] = '#';
        temp[j] = '\0';
        for(int i = 0 ; i <2*s.length()+1 ; ++i)
        {
            int j = i;
            int z = i;
            int count=0;
            //计算奇数最长回文字符串
            while((++z<(2*s.length()+1)) && (--j>=0) && (temp[z] == temp[j]))
            {
                count++;
                if(count > max)
                {
                    max=count;
                    idx = i;
                }
            } 

        }
        return s.substr((idx-max)/2,max);
    }
};

3.动态规划法

DP算法的思想就是记录每一个回文子串的位置,在每一次判断是否为回文子串的时候先判断它的子串是不是回文,例如,用map[i][j]记录i到j为回文数组,如果这个时候s[i-1]==s[j+1],那么就能在O(1)时间内判断[i-1,j+1]是否为回文了。

动态规划法的时间复杂度为O(n^2).

class Solution {
public:
    string longestPalindrome(string s) {
        int len = s.length();
        int idx = 0;//记录最长回文字符的开始处
        int max = 1;//记录最长回文字符的长度
        int map[1000][1000] = {0};//记录i到j是否为回文子串
        for(int i = 0 ; i < len ; ++i)
        {
            map[i][i] = 1;//初始化长度为1的回文子串
        }
        for(int i = 0 ; i < len ; ++i)
        {
            if(s[i] == s[i+1])//初始化长度为2的子串
            {
                map[i][i+1] = 1;
                idx = i;
                max = 2;
            }
        }

        for(int plen = 3 ; plen <= len ; plen++)//从长度为3开始算起
        {//plen代表当前判断的回文子串的长度
            for(int j = 0 ; j < len - plen +1 ; j++)
            {
                int z = plen+j-1;//z为回文子串的尾序号
                if (s[j] == s[z] && map[j+1][z-1]) {
                //O(1)时间内判断j到z是否回文
                    map[j][z] = 1;
                    idx = j;
                    max = plen;
                }
            }
        }
        return s.substr(idx,max);//返回子串
    }
};

4.经典的Manacher算法,O(n)复杂度

算法步骤:

step1:跟解法2一样,改造字符串:

abba –> $#a#b#b#a#

注:加’$’是为了避免处理越界问题

step2:用p[i]记录以i为中心点的回文字符串长度

改造后的字符串:$#a#b#b#a#

p[]数组的值:121242121

注:p[i]-1 = 源字符串中回文子串长度

step3:利用DP的思想来求解p[]

利用中心扩展法求以i为中心的最长回文串

while(i+p[i] < temps.length() && temps[i-p[i]] == temps[i+p[i]]) p[i]++;

利用p[],mx,id记录的已有回文字符串的长度来避免大量重复的匹配

if(mx > i) p[i] = p[2*id-i] < (mx-i) ? p[2*id-i]:(mx-i);

注:p[2*id-i]为i关于j对称的点的回文串长度

mx为i之前的回文串延伸到右边的最长位置,id为该回文串的中间值

class Solution {
public:
    string longestPalindrome(string s) {
        string temps;
        temps+="$#";//加$是为了避免处理越界情况,减小时间复杂度
        for(int i = 0 ; i < s.length() ; ++i)//
        {
            temps+=s[i];
            temps+="#";
        }
        int *p = new int[temps.length()];//p[i]记录以i为中心的回文串长度
        memset(p, 0, sizeof(p));

        int max = 0,idx = 0;//max记录最长回文串的长度,idx记录最长回文串的中心位置
        int mx = 0,id = 0;//mx记录i之前的最长回文串延伸到最右边的位置,id记录该字符串的中心位置
        for(int i = 1; i < temps.length() ; ++i)
        {
            if(mx > i)
            {
                p[i] = p[2*id-i] < (mx-i) ? p[2*id-i]:(mx-i);
            }
            else
                p[i] = 1;

            while(i+p[i] < temps.length() && temps[i-p[i]] == temps[i+p[i]])
            {
                p[i]++;
            }
            if(i+p[i]>mx)
            {
                id = i;
                mx = i+p[i];
                if(p[i]>max)
                {
                    max = p[i];
                    idx = id;
                }
            }
        }
        max--;
        return s.substr((idx-max)/2,max);
    }
};

该算法的时间复杂度为O(n)。

以上代码在LeetCode中均Accepted。

【一天一道LeetCode】#5 Longest Palindromic Substring的更多相关文章

  1. LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法

    LeetCode(4) || Longest Palindromic Substring 与 Manacher 线性算法 题记 本文是LeetCode题库的第五题,没想到做这些题的速度会这么慢,工作之 ...

  2. Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法)

    Leetcode 5. Longest Palindromic Substring(最长回文子串, Manacher算法) Given a string s, find the longest pal ...

  3. 求最长回文子串 - leetcode 5. Longest Palindromic Substring

    写在前面:忍不住吐槽几句今天上海的天气,次奥,鞋子里都能养鱼了...裤子也全湿了,衣服也全湿了,关键是这天气还打空调,只能瑟瑟发抖祈祷不要感冒了.... 前后切了一百零几道leetcode的题(sol ...

  4. LeetCode 5 Longest Palindromic Substring(最长子序列)

    题目来源:https://leetcode.com/problems/longest-palindromic-substring/ Given a string S, find the longest ...

  5. 【JAVA、C++】LeetCode 005 Longest Palindromic Substring

    Given a string S, find the longest palindromic substring in S. You may assume that the maximum lengt ...

  6. leetcode:Longest Palindromic Substring(求最大的回文字符串)

    Question:Given a string S, find the longest palindromic substring in S. You may assume that the maxi ...

  7. [LeetCode][Python]Longest Palindromic Substring

    # -*- coding: utf8 -*-'''__author__ = 'dabay.wang@gmail.com'https://oj.leetcode.com/problems/longest ...

  8. 【LeetCode】Longest Palindromic Substring 解题报告

    DP.KMP什么的都太高大上了.自己想了个朴素的遍历方法. [题目] Given a string S, find the longest palindromic substring in S. Yo ...

  9. [LeetCode] 5. Longest Palindromic Substring 最长回文子串

    Given a string s, find the longest palindromic substring in s. You may assume that the maximum lengt ...

  10. 最长回文子串-LeetCode 5 Longest Palindromic Substring

    题目描述 Given a string S, find the longest palindromic substring in S. You may assume that the maximum ...

随机推荐

  1. python语言学习

    前段时间要做视频直播需要编写自动模块,就考虑使用python脚本语言,python的好多语法都是很独特的,比如数据类型不需要预定义,缩进的方式等,另外功能也很强大,豆瓣就是用python写的.我写的部 ...

  2. Sqoop-1.4.5用户手册

    本文以Sqoop User Guide (v1.4.5)为主,对Sqoop-1.4.5的用户手册进行翻译,同时会结合一些实际操作中的注意事项一并写入.由于原文档很长,本文首先会以实际使用到的部分为主, ...

  3. CCSpriteBatchNode中存放元素的一点理解

    该对象只能包含基于CCSprite的对象,并且该要求适用于一切子孙对象.即加入CCSpriteBatchNode的任何对象都必须是CCSprite或其子类. 比如CCSpriteBatchNode包含 ...

  4. cocos2dx 3.2之Lua打飞机项目

    1          创建lua打飞机项目 cocos new T32Lua -dE:\Installed\cocos2d-x-3.2\cocos2d-x-3.2\projects -l lua 2 ...

  5. (一二九)获取文件的MineType、利用SSZipArchive进行压缩解压

    MineType 简介 文件在网络上以二进制流的方式传播,为了区分不同的文件类型,用MineType来标明. 为什么要获取 文件的拓展名较短,比较好记,但是MineType是很长的,比如docx拓展名 ...

  6. FORM级别和数据库级别的Trace

     metalink上的文章较全的,中文的可参考我的博客EBS开发技术之trace http://blog.csdn.net/cai_xingyun/article/details/17250971 ...

  7. 【一天一道LeetCode】#205. Isomorphic Strings

    一天一道LeetCode 本系列文章已全部上传至我的github,地址:ZeeCoder's Github 欢迎大家关注我的新浪微博,我的新浪微博 欢迎转载,转载请注明出处 (一)题目 Given t ...

  8. iOS动画进阶 - 教你写 Slack 的 Loading 动画

    (转载自:http://blog.csdn.net/wang631106979/article/details/52473985) 如果移动端访问不佳,可以访问我的个人博客 前几天看了一篇关于动画的博 ...

  9. pig强制转换(字符到整数):首位0怎么处理,‘01’到1的转化,

    pig支持的类型转换(cast) Pig Latin supports casts as shown in this table. from / to bag tuple map int long f ...

  10. Uva - 1607 - Gates

    题目理解麻烦,估计提交量少(总共只有32个人...)也是因为题目比较麻烦,看起来像物理题,实际理解了还可以.整个电路的功能就4种,先判断x=0和x=1的输出是否相同,吐过相同,而整个电路是常熟,随便输 ...