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)