zoukankan      html  css  js  c++  java
  • 九度OJ 1528 最长回文子串 -- Manacher算法

    题目地址:http://ac.jobdu.com/problem.php?pid=1528

    题目描述:

    回文串就是一个正读和反读都一样的字符串,比如“level”或者“noon”等等就是回文串。
    回文子串,顾名思义,即字符串中满足回文性质的子串。
    给出一个只由小写英文字符a,b,c...x,y,z组成的字符串,请输出其中最长的回文子串的长度。

    输入:

    输入包含多个测试用例,每组测试用例输入一行由小写英文字符a,b,c...x,y,z组成的字符串,字符串的长度不大于200000。

    输出:

    对于每组测试用例,输出一个整数,表示该组测试用例的字符串中所包含的的最长回文子串的长度。

    样例输入:
    abab
    bbbb
    abba
    样例输出:
    3
    4
    4
    来源:
    腾讯2013年实习生招聘二面面试题

    自己比较野蛮的方法

    #include <stdio.h>
    #include <string.h>
     
    int LenOfMaxPalindrome(char str[], int len, int low, int high){
        int sum = 0;
        while (low >= 0 && high < len){
            if (str[low] == str[high]){
                sum += 2;
                --low;
                ++high;
            }
            else
                break;
        }
        return sum;
    }
     
    int MaxPalindrome (char str[]){
        int len = strlen (str);
        int mid;
        int len1;
        int len2;
        int max;
     
        if ((len >= 2) && (str[0] == str[1]))
            max = 2;
        else
            max = 1;
        for (mid=1; mid<len-1; ++mid){
            len1 = len2 = 0;
            len1 = LenOfMaxPalindrome(str, len, mid - 1, mid + 1) + 1;
            if (str[mid] == str[mid + 1]){
                len2 = LenOfMaxPalindrome(str, len, mid - 1, mid + 2) + 2;
            }
            if (len1 < len2)
                len1 = len2;
            if (max < len1)
                max = len1;
        }
         
        return max;
    }
     
    int main(void){
        char str[200001];
     
        while (scanf ("%s", str) != EOF){
            printf ("%d
    ", MaxPalindrome (str));
        }
     
        return 0;
    }

    O(n)的回文子串Manacher算法(详细算法讲解见参考资料)

    算法代码实现如下:

    #include <stdio.h>
     
    void Manacher (char str[], int len, int Radix[]){
        int mx = 0;    //记录被影响到的最远的位置
        int id = 0;    //最长影响串的位置
        Radix[0] = 0;
        int i;
        for (i=1; i<len; ++i){
            Radix[i] = 1;
            if (mx > i){
                Radix[i] = Radix[2 * id - i];
                if (mx - i < Radix[i])
                    Radix[i] = mx - i;
            }
            while (str[i - Radix[i]] == str[i + Radix[i]])
                ++Radix[i];
            if (i + Radix[i] > mx){
                mx = i + Radix[i];
                id = i;
            }
        }
    }
     
    int Preproccess (char str[], char old_str[]){
        int index;
        int len;
        char middle = '#';
        str[0] = '$';
        str[1] = middle;
        index = 0;
        len = 2;
        while (old_str[index]){
            str[len++] = old_str[index++];
            str[len++] = middle;
        }
        str[len] = '?';
        return len;
    }
     
    int main(void){
        char old_str[200001];
        char str[400004];
        int Radix[400004];
        int len;
        int i;
        int ans;
     
        while (scanf ("%s", old_str) != EOF){
             len = Preproccess (str, old_str);
             Manacher (str, len, Radix);
             ans = 0;
             for (i=1; i<len; ++i){
                if (ans < Radix[i])
                    ans = Radix[i];
             }
             printf ("%d
    ", ans - 1);
        }
        return 0;
    }

    参考资料:http://tiankonguse.com/blog/?p=84

                     http://www.cnblogs.com/biyeymyhjob/archive/2012/10/04/2711527.html

                     http://www.akalin.cx/longest-palindrome-linear-time

                     http://leetcode.com/2011/11/longest-palindromic-substring-part-i.html

                     http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html


    相思题目:https://oj.leetcode.com/problems/longest-palindromic-substring/

  • 相关阅读:
    C# 设计模式
    FutureTask、Fork/Join、 BlockingQueue
    线程的几种创建方式
    行锁、表锁、乐观锁、悲观锁
    J.U.C之AQS
    同步容器并发容器
    线程不安全类
    线程封闭
    不可变对象
    安全发布对象—单例模式
  • 原文地址:https://www.cnblogs.com/liushaobo/p/4373781.html
Copyright © 2011-2022 走看看