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; } };