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:
Given words
= ["bat", "tab", "cat"]
Return [[0, 1], [1, 0]]
The palindromes are ["battab", "tabbat"]
Example 2:
Given words
= ["abcd", "dcba", "lls", "s", "sssll"]
Return [[0, 1], [1, 0], [3, 2], [2, 4]]
The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"]
Credits:
Special thanks to @dietpepsi for adding this problem and creating all test cases.
利用Map来实现匹配。把每个字符串的逆转存储起来,如果一个字符串是回文的化。比如p是回文,由a和b组成。那么一定有(a'表示a的逆转)
p = [a b] p' = [b' a'] ; 由于 p = p'
[a b] = [b' a'] 如果 a 比 b 大 ,说明 a = b' + a.substr是回文。 此时[a b]回文
同理如果 b比a大 , b = a' + b.substr是回文。此时[b a ] 回文。
只要遍历每个a找到,字串的逆转是否在map中,同时剩下a的字串是回文串,说明[a b] 是一组解。
复杂度是O(N*k) k是平均字串长度。
class Solution {
public:
vector<vector<int>> palindromePairs(vector<string>& words) {
unordered_map<string,int> Match; //string字符串反转存储起来,用于匹配palindrome
vector<vector<int>> ans; //结果
for(int i=0; i<words.size(); ++i){
string rev = words[i];
reverse(rev.begin(),rev.end());
Match[rev] = i;
}
if(Match.find("")!=Match.end()){
for(int i=0; i<words.size(); ++i){
if(i!=Match[""]&&palindrome(words[i]))
ans.push_back({Match[""],i}); //Corner Case {"",palindrome}
}
}
for(int i=0 ; i<words.size(); ++i){
for(int k=0; k<words[i].size(); ++k){
string left = words[i].substr(0,k);
string right = words[i].substr(k,words[i].size()-k);
if(Match.find(left)!=Match.end()&&palindrome(right)&&Match[left]!=i)
//left palindrome left' ,Corner Case {palindrome,""}
ans.push_back({i,Match[left]});
if(Match.find(right)!=Match.end()&&palindrome(left)&&Match[right]!=i)//right' palindrome right
ans.push_back({Match[right],i});
}
}
return ans;
}
bool palindrome(string a){ //判断是否为回文
int i = 0;
int j = a.size()-1;
while(i<j){
if(a[i]!=a[j])
return false;
++i;
--j;
}
return true;
}
};