题目描述
给定一组 互不相同 的单词, 找出所有不同 的索引对(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"]
算法1
两个单词能组成回文 那么有以下三种情况
1 两个互为逆序 abc cba
2 较短的是较长的部分单词的逆序 较长单词除开互为逆序的部分
剩余部分是回文 比如 abcec ba 或者 lls s
注意可能有 “a” “”这种特殊词汇 不过也可以归到上述两种情况
C++ 代码
class Solution {
public:
unordered_map<string, int> mm;
vector<vector<int>> ans;
set<vector<int>> vis;
bool CheckIsPal(const string& s)
{
bool ret = false;
if (s == "") return true;
int l = 0; int r = s.size()-1;
while (l < r) {
if (s[l] != s[r]) return false;
l++; r--;
}
ret = true;
return ret;
}
void solve(const string& s,int idx, int isReverse)
{
if (isReverse == 0) {
for (int i = 0; i <= s.size(); i++) {
string check = s.substr(0, i);
string find = s.substr(i);
reverse(find.begin(), find.end());
if (mm.count(find) && CheckIsPal(check) && idx != mm[find] ) {
if (vis.count({ mm[find], idx }) == 0) {
ans.push_back({ mm[find], idx });
vis.insert({ mm[find], idx });
}
}
}
}
else {
for (int i = s.size(); i >= 0; i--) {
string check = s.substr(i);
string find = s.substr(0, i);
reverse(find.begin(), find.end());
if (mm.count(find) && CheckIsPal(check) && idx != mm[find]) {
if (vis.count({ idx,mm[find] }) == 0) {
ans.push_back({ idx,mm[find] });
vis.insert({ idx, mm[find] });
}
}
}
}
}
vector<vector<int>> palindromePairs(vector<string>& words) {
for (int i = 0; i < words.size(); i++) {
mm[words[i]] = i;
}
for (int i = 0; i < words.size(); i++) {
string s = words[i];
solve(s, i,0);
solve(s, i,1);
}
return ans;
}
};
堪堪AC 时间差点TLE