题目:336. 回文对
给定一组 互不相同 的单词, 找出所有不同 的索引对(i, j),使得列表中的两个单词, words[i] + words[j] ,可拼接成回文串。
示例 1:
输入:["abcd","dcba","lls","s","sssll"]
输出:[[0,1],[1,0],[3,2],[2,4]]
解释:可拼接成的回文串为 ["dcbaabcd","abcddcba","slls","llssssll"]
示例 2:
输入:["bat","tab","cat"]
输出:[[0,1],[1,0]]
解释:可拼接成的回文串为 ["battab","tabbat"]
来源:力扣(LeetCode)
链接:https://leetcode-cn.com/problems/palindrome-pairs
著作权归领扣网络所有。商业转载请联系官方授权,非商业转载请注明出处。
基本思想:从构成回文串的两个字符串的特征出发
这道题用暴力方法是行不通的。
构成回文串的两个子串的特征:
- 该字符串本身是回文串,那么它和一个空字符串可以构成两个回文对
- 字符串序列中存在一个该字符串的逆串,两个字符串拼接可以形成回文串
- 字符串的前一部分或者后一部分是回文串,另一部分的逆串在字符串序列中,两个字符串拼接可以形成字符串
class Solution {
public:
unordered_map<string, int> m;
vector<vector<int>> palindromePairs(vector<string>& words) {
for(int i = 0; i < words.size(); ++i){
string s = words[i];
reverse(s.begin(), s.end());
m[s] = i;
}
vector<vector<int>> res;
for(int i = 0; i < words.size(); ++i){
if(words[i] == "")
continue;
if(m.count(words[i]) && m[words[i]] != i){
res.push_back({
i, m[words[i]]});
}
for(int j = 0; j < words[i].size(); ++j){
if(isPalindrome(words[i], 0, j)){
string temp = words[i].substr(j + 1, words[i].size() - j - 1);
if(m.count(temp)){
res.push_back({
m[temp], i});
}
}
if(isPalindrome(words[i], j, words[i].size() - 1)){
string temp = words[i].substr(0, j);
if(m.count(temp)){
res.push_back({
i, m[temp]});
}
}
}
}
return res;
}
bool isPalindrome(string s, int l, int r){
while(l < r){
if(s[l++] != s[r--])
return false;
}
return true;
}
};