2014再见 2015你好 【附带】[LeetCode]最长回文子串

前天晚上考完数理逻辑感觉还比较良好,昨天下午考完组合数学就不好了。一道大题没想出来,本以为用最后的10分钟划了两笔,结果告诉我收卷。看错时间了真可悲。其实也没什么好遗憾的,人家刷一整本书习题的大有人在啊!我干了什么呀?根本没好好复习。都是活该。

今天2014最后一天。上午迟迟来实验室。中午吃完饭回去开始看《奇葩说》,一连看四集,就唰唰唰过去三个小时了。又写了一会儿助教工作心得,填几个表格,就到了晚饭点了……晚上还有多媒体的课。最后一节,冷冷清清。做报告,讲完一个走一个,最后加老师只剩四个人。

寝室里那三人冒着今天的冷风去吃德川家了,跨年了嘛,放肆一下。我要不是因为这是我boss的课我也走了。不过感谢boss,让我省了一大笔钱。德川家好吃是好吃,199一位对学生来讲还是太高昂了。今天降温,很冷,好像很多人都无心在实验室呆着了。唯独武老师还在办公室。

本来说晚上去K歌刷夜的,这都九点半了也没动静啊都。一想到回学校的火车票根本抢不到这个事儿就很苦恼,这年头买个票真难。曾经以为社会的不公平,一个细节就体现在网络订票的欺负电话订票的,电话订票的欺负半夜就去窗口排队的。现在看来,在网络购票这群人里都已经分化出阶层来了,就是用抢票软件的和老老实实刷新网页的。前一阵子12306数据库流出来,据传就是大家使用的第三方抢票软件造成的。但是什么都不能阻挡他们接着用!


算了,我还有好几个课程论文要写。但这会儿写不下去,我搞点算法吧。昨晚看Leetcode,pick one捞到一个最长回文子串的题。上网查了一下,解法还是挺多的。一眼瞄到了一个Manacher算法,O(n)复杂度,而且思想还比较简单。真是牛!

具体可以参照这个:http://blog.163.com/zhaohai_1988/blog/static/2095100852012716105847112/,它还链到一个Leetcode的网站上。

/**
改编自http://leetcode.com/2011/11/longest-palindromic-substring-part-ii.html
**/
#include<bits/stdc++.h>
using namespace std;
// Transform S into T.
// For example, S = "abba", T = "^#a#b#b#a#$".
// ^ and $ signs are sentinels appended to each end to avoid bounds checking
string preProcess(string s) {
    int n = s.length();
    if (n == 0) return "^$";
    string ret = "^";
    for (int i = 0; i < n; i++)
        ret += ("#" + s.substr(i, 1));

    ret += "#$";
    cout<<ret<<endl;
    return ret;
}

string longestPalindrome(string s) {
    string T = preProcess(s);
    int n = T.length();
    int *P = new int[n];
    int C = 0, R = 0;  //Center, Right range
    for (int i = 1; i < n-1; i++) {
        int i_mirror = 2*C-i; // equals to i' = C - (i-C)
        P[i] = (R > i) ? min(R-i, P[i_mirror]) : 0;

        // Attempt to expand palindrome centered at i
        for(; T[i+P[i]] == T[i-P[i]]; P[i]++)

        // If palindrome centered at i expand past R,
        // adjust center based on expanded palindrome.
        if (i + P[i] > R) {
            C = i;
            R = i + P[i];
        }
    }

    // Find the maximum element in P.
    int maxLen = 0;
    int centerIndex = 0;
    for (int i = 1; i < n-1; i++) {
        if (P[i] > maxLen) {
            maxLen = P[i];
            centerIndex = i;
        }
    }
    delete[] P;
    printf("中心位置:%d,最大长度:%d\n",centerIndex,maxLen);
    return s.substr((centerIndex - maxLen)/2, maxLen-1);
}
int main()
{
    int i, ans;
    string s;
    s = "waabwswfd";
    //while(cin>>s){
        cout<<longestPalindrome(s);
    //}
    return 0;
}


下面是python的

class Solution:
    def longestPalindrome(self, s):
        ns = '^#' + '#'.join(s) + '#$'
        i = 0
        mx = 0   
        C = 0
        p = [1] * len(ns)
        for i in xrange(1,len(ns)-1):
            if mx > i:
                p[i] = min(p[2*C-i],mx-i)  #j = 2*C-i
 
            while ns[i-p[i]]==ns[i+p[i]]:
                p[i] += 1
 
            if mx < p[i]+i:
                mx = p[i] + i
                C = i
        
        maxp = 0
        pk = 0
        for k in xrange(len(p)):
            if p[k] > maxp:
                pk = k
                maxp = p[k]

        return s[(pk-maxp+1)/2:(pk+maxp-1)/2]

sol = Solution()
print sol.longestPalindrome('0896957759208588502650624860')


评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值