lc 336. Palindrome Pairs

https://leetcode.com/problems/palindrome-pairs/description/

给一个list[str],找到所有两个可以连接成回文的下标可能。

 

开始以为会有高级的算法,后来发现只是一个优化加速一下的问题。最大的经验教训就是,拿到一个题先想想是不是初步想法就能a掉,万一人家就没考深层次的奇葩算法呢。

题解里面给的是n*n*k,下面我的算法是n*k*k,这样算是一个不小的加速,注意python里set的查找操作是o(1)的。

先a+b是一个回文串有3中可能:

1.len(a)=len(b)

2.len(a)>len(b)

3.len(a)<len(b)

如果情况1,那么这种情况直接检测一下即可。

情况2,就意味着a的最后有一段自己的回文,比如a="syy"这种,最后可以自己内部消耗一下,也可能a="xyz",b="yx"这种,a最后的一个字母"z"自己和自己是回文。

情况3类似。

对于每个单词w,我们找w前面后面可能有的子回文串长度,比如w="abaca",那么前面可以有a,aba,后面可以有a,aca,再比如对w="lls",前面可以有l,ll,后面只有s。

然后去掉这部分子回文前/后缀,直接去查找剩下的部分是否在words中存在即可。

注意处理:

1.w本身是回文

2.words中有空串

 

code:

class Solution:
    def palindromePairs(self, words):
        """
        :type words: List[str]
        :rtype: List[List[int]]
        """
        s={}
        for i in range(len(words)):
            s[words[i]]=i
        def ofP(w,x=None,y=None):
            if x==None:
                x=0
                y=len(w)-1
            ans=w[x:y+1]
            ans=reversed(ans)
            return ''.join(ans)
        def isP(w,x,y):
            i=x
            j=y
            while i<j:
                if w[i]!=w[j]:
                    return False
                i+=1
                j-=1
            return True
        def bP(w):
            ans=[]
            for j in range(len(w)-1):
                if isP(w,0,j):
                    ans.append(j)
            return ans
        def eP(w):
            ans=[]
            for i in range(1,len(w)):
                if isP(w,i,len(w)-1):
                    ans.append(i)
            return ans
        blank=None
        if '' in s:
            blank=s['']

        ans=set()
        for i in range(len(words)):
            w=words[i]
            if w=='':
                continue
            if isP(w,0,len(w)-1):
                if blank!=None:
                    ans.add((blank,i))
                    ans.add((i,blank))
            else:
                p=ofP(w,0,len(w)-1)
                if p in s:
                    p=s[p]
                    ans.add((p,i))
                    ans.add((i,p))
            bs=bP(w)
            es=eP(w)
            for b in bs:
                rest=ofP(w[b+1:])
                if rest in s:
                    ans.add((s[rest],i))
            for e in es:
                rest=ofP(w[:e])
                if rest in s:
                    ans.add((i,s[rest]))
        return list(ans)

 

posted @ 2018-10-04 01:08  Cloud.9  阅读(192)  评论(0编辑  收藏  举报