string
palindrome
hash table
]
Leetcode 0336. Palindrome Pairs
Problem statement
https://leetcode.com/problems/palindrome-pairs/
Solution
Let n
be number of words and k
be average length of word. Then there is trivial algorithm with complexity O(n^2k)
. There is better algorithm: for each word we can evaluate all prefixes and suffixes, and check if they are palindromes: for example if we have abcxxyxx, cba
, if we want to combine them we need suffix xxyxx
to be palindrome; if we want to combine abc, xyyxcba
, we want prefix xyyx
to be palindrome. So we do the following steps:
- For each word, and each suffix/prefix of length
i
, we check if it is palindrome and if it is, we put prefix/suffix to our hash tableW_d
. Note, that for the caseabcxxyxx
we found suffixxxyxx
which is palindrome, but we put prefixabc
to our hash table. Note also that we need to handle the cases of empty suffixes/prefixes. For example if we haveabc
andcba
, then we can connect these two strings in two ways, and we can say that we take empty prefix/suffix here. So, what will be kept inW_d
is pairs(t, ind)
, whereind
is index of word and first element is-1
for non-empty prefix,1
for non-empty suffix and0
for empty suffix or prefix. - Now, we want to iterate through our
W
once again and for any word we look atW_d[word[::-1]]
: possible candidates for this word. We need to make sure that candidate we found is not equal to word we consider at the moment. Next, ifone < 0
, it means, that we consider non-empty prefixes, that is why we considerone <= 0
and append pair to our final answer. Same logic is forone >= 0
. In this way for non-empty prefixes/suffixes we will deal with them only once and for empty we deal with them twice as it should be. - In the end we remove duplicates: return set.
Complexity
For each word we make O(k^2)
preprocessing, so in total we have O(nk^2)
time for the first step. For the second step we traverse each element in values of W_d
only once and we have no more than O(n^2)
of them, so total time complexity is O(nk^2 + n^2)
. Space complexity is O(n^2)
.
Code
class Solution:
def palindromePairs(self, W):
W_d, ans = defaultdict(list), []
for idx, word in enumerate(W):
W_d[word].append([0, idx])
for i in range(1, len(word) + 1):
suff, pref = word[:i], word[i:]
if suff == suff[::-1]:
W_d[pref].append([- (pref != ""),idx])
if pref == pref[::-1]:
W_d[suff].append([+ (suff != ""),idx])
for idx, word in enumerate(W):
for one, two in W_d[word[::-1]]:
if idx != two and one <= 0:
ans.append((idx, two))
if idx != two and one >= 0:
ans.append((two, idx))
return set(ans)