题目: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.
给定一个序列包含若干个不重复的字符串,任意将其中两个字符串连接,看是否能组成回文串,返回所有能组成回文串的序号对。
思路:判断一个字符串是否是回文串不难,直接判断两个字符串拼接是否回文串时间的话,时间复杂度是O(n²)。所以要借助空间换时间,用一个map来存所有的字符串,遍历一次序列,对每个字符串生成回文串,再从map里面找。首先分析怎么样的字符串能成为回文串。回文串的字符串所有字母以中心点对称,将每个字符串A分成左右两部分,如果左边部分是回文的,右边部分与另一个字符串B是对称的,那么字符串A和B拼接就能生成一个回文串,A在右边。如果右边部分是回文的,左边部分与另一个字符串B是对称的,那么字符串A和B就能拼接成生成一个回文串,A在左边。最后要考虑特殊情况空字符串,不能将其长度认为是0,可以把空字符串分成左右两个空字符串。这样就能在O(n)的时间复杂度之内求出结果。
class Solution {
public:
vector<vector<int>> palindromePairs(vector<string> &words)
{
vector<vector<int> > ans;
unordered_map<string, int> dic;
int n = words.size();
for (int i = 0; i < n; ++i)
dic[words[i]] = i;
for (int i = 0; i < n; ++i)
{
string temp = words[i];
dic.erase(temp);
for (int j = 0; j <= temp.length(); ++j)
{
string L = temp.substr(0, j);
string R = temp.substr(j, temp.length());
string revL, revR;
revL = revL.assign(L.rbegin(), L.rend());
revR = revR.assign(R.rbegin(), R.rend());
if (j != temp.length() && dic.count(revL) != 0 && isPalindrome(R))
ans.push_back(vector<int>{i, dic[revL]});
if (dic.count(revR) != 0 && isPalindrome(L))
ans.push_back(vector<int>{dic[revR], i});
}
dic[temp] = i;
}
return ans;
}
bool isPalindrome(string s)
{
for (int i = 0; i < s.length(); ++i)
{
if (s[i] != s[s.length() - i - 1])
return false;
}
return true;
}
};