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"]
分析
这一道题可以用TRIE树来做,使用TRIE树记录所有word的倒序,然后遍历words,针对每一个word在TIRE树中寻找是否有字符串与该word组成回文数。判断的方法是:遍历word的字符查看是否存在TRIE树中,如果不存在,直接返回失败;如果存在,并且word到结尾了,那么沿着当前的TRIE树继续向下找,看剩余的字符串能否构成回文数;如果TRIE树寻找到结尾但word还有剩余,那就看word剩余的部分是否是回文数。
还有一种比较巧妙的方法,如果word[0, i]是回文数,那么就将word[i+1, end]颠倒,在words中寻找是否存在,如果存在则可以构成回文数;如果word[i, end]是回文数,那么就将word[0, i-1]颠倒,在words中寻找是否存在。这个原理跟上面的TRIE树相同。
Code
class Solution {
public:
vector<vector<int>> palindromePairs(vector<string>& words) {
int length = words.size();
map<string, int> dict;
for (int i = 0; i < length; i ++)
{
dict.insert(make_pair(words[i], i));
}
vector<vector<int>> res;
for (int i = 0; i < length; i ++)
{
string word = words[i];
int wordLen = word.size();
string reverWord = words[i];
int m = 0;
int n = wordLen-1;
vector<int> tmp(2, 0);
dict.erase(word);
while (m < n)
{
swap(reverWord[m], reverWord[n]);
m ++;
n --;
}
if (dict.find(reverWord) != dict.end())
{
tmp[0] = i;
tmp[1] = dict[reverWord];
res.push_back(tmp);
}
for (int j = 0; j < wordLen; j ++)
{
if (isPalindrome(word.substr(0, j+1)))
{
if (dict.find(reverWord.substr(0, wordLen - j - 1)) != dict.end())
{
tmp[1] = i;
tmp[0] = dict[reverWord.substr(0, wordLen - j - 1)];
res.push_back(tmp);
}
}
if (isPalindrome(word.substr(j, wordLen - j)))
{
if (dict.find(reverWord.substr(wordLen-j, j)) != dict.end())
{
tmp[0] = i;
tmp[1] = dict[reverWord.substr(wordLen-j, j)];
res.push_back(tmp);
}
}
}
dict.insert(make_pair(word, i));
}
return res;
}
bool isPalindrome(const string& word)
{
int length = word.size();
if (length == 0)
return true;
int i = 0;
int j = length - 1;
while (i < j)
{
if (word[i] != word[j])
return false;
i ++;
j --;
}
return true;
}
};
运行效率
Runtime: 388 ms, faster than 27.09% of C++ online submissions forPalindrome Pairs.
Memory Usage: 61.8 MB, less than 50.00% of C++ online submissions forPalindrome Pairs.