# 336. Palindrome Pairs

**<font color=red>难度: Hard</font>**

## 刷题内容

> 原题连接

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

> 内容描述

```

Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.

Example 1:

Input: ["abcd","dcba","lls","s","sssll"]
Output: [[0,1],[1,0],[3,2],[2,4]] 
Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"]
Example 2:

Input: ["bat","tab","cat"]
Output: [[0,1],[1,0]] 
Explanation: The palindromes are ["battab","tabbat"]
```

## 解题方案

> 思路 1
******- 时间复杂度: O(N^2)******- 空间复杂度: O(1)******


对于每一个word，我们只需要算出它的所有prefix和suffix，

```
比如‘abc’：
它的所有prefix为'', 'a', 'ab', 'abc'
它的所有suffix为'', 'c', 'cb', 'cba'
```

现在有两种情况：

1. 如果前缀pref是回文且后缀suff的reverse也在words里面，那么suff[::-1]+(pref+suff)肯定是回文, 注意其中suff[::-1]不能等于word本身
2. 如果后缀suff是回文且前缀pref的reverse也在words里面，那么(pref+suff)+pref[::-1]肯定是回文, 注意其中pref[::-1]不能等于word本身

***但是！！！我们不要忘记直接这样算会有duplicates，例如:***
```
输入为["abcd","dcba"]

直接按照上面的算法我们会返回[[0,1], [1,0], [0,1], [1,0]]

但实际上应该返回[[0,1], [1,0]]

那么究竟为什么会有重复呢？
因为前面验证第一种情况的时候计算了'abcd'+(''+'dcba')和'dcba'+(''+'abcd')的情况
后面验证第二种情况的时候我们又计算了('abcd'+'')+'dcba'和(‘dcba'+'')+'abcd'的情况

这就导致了重复，所以在计算第二种情况的时候我们要排除suffix就是word本身的情况
```

beats 89.80%

```python
class Solution(object):
    def palindromePairs(self, words):
        """
        :type words: List[str]
        :rtype: List[List[int]]
        """
        lookup = {
            word: i for i, word in enumerate(words)
        }
        res = []
        for i, word in enumerate(words):
            for j in range(len(word)+1):
                pref, suff = word[:j], word[j:]
                # 如果后缀suff是回文且前缀pref的reverse也在words里面，那么(pref+suff)+pref[::-1]肯定是回文
                if suff == suff[::-1] and pref[::-1] in lookup and pref[::-1] != word:
                    res.append([i, lookup[pref[::-1]]])
                # 如果前缀pref是回文且后缀suff的reverse也在words里面，那么suff[::-1]+(pref+suff)肯定是回文
                if pref == pref[::-1] and suff[::-1] in lookup and suff[::-1] != word:
                    # 这是为了保证没有重复，例如：
                    # 如果前面算了'abcd'+(''+'dcba')和'dcba'+(''+'abcd')的情况
                    # 后面不能再算一遍('abcd'+'')+'dcba'和(‘dcba'+'')+'abcd'了
                    if j != 0:
                        res.append([lookup[suff[::-1]], i])
        return res
```





























