题目大意:给出一组字符串,输出所有的两个字符串拼接能够形成回文串的组合
样例输入:[“abcd”,“dcba”,“lls”,“s”,“sssll”]
样例输出:[[0,1],[1,0],[3,2],[2,4]]
思路:枚举所有可能的拼接情况,判断每次拼接是否是回文串,TLE。
暴力代码:
class Solution {
private:
bool isHuiWen(string a){
int i = 0, j = a.size()-1;
while (i < j){
if (a[i] != a[j]) return false;
i++;j--;
}
return true;
}
public:
vector<vector<int>> palindromePairs(vector<string>& words) {
vector<vector<int>> ans;
int len = words.size();
for (int i = 0; i < len; i++){
for (int j = i+1; j < len; j++){
if (isHuiWen(words[i]+words[j])){
vector<int> t;t.push_back(i);t.push_back(j);
ans.push_back(t);
}
if (isHuiWen(words[j]+words[i])){
vector<int> t;t.push_back(j);t.push_back(i);
ans.push_back(t);
}
}
}
return ans;
}
};
优化思路:假设拼接的字符串为 a , b a,b a,b,不妨设 l e n ( a ) > = l e n ( b ) len(a)>=len(b) len(a)>=len(b),如果 a a a和 b b b拼接后的字符串是回文串,那么字符串 a a a的前 l e n ( b ) len(b) len(b)个字符串是字符串 b b b的转置,且 a a a剩余的字符串也是回文串。
实现方法:使用 m a p < s t r i n g , i n t > map<string,int> map<string,int>记录所有字符串和下标,对于每一个字符串,判断其每一个子串是否是回文串,剩余部分的转置是否与其他字符串相同
AC代码:
class Solution {
private:
map<string, int> mp;
bool isHuiWen(string s, int a, int b){
int i = a, j = b;
while (i < j){
if (s[i] != s[j]) return false;
i++;j--;
}
return true;
}
public:
vector<vector<int>> palindromePairs(vector<string>& words) {
vector<vector<int>> ans;
int len = words.size();
for (int i = 0; i < len; i++){
mp[words[i]] = i;
}
for (int i = 0; i < len; i++){
int m = words[i].size();
for (int j = 0; j <= m; j++){
if (isHuiWen(words[i], j, m-1)){
string t = words[i].substr(0, j);
reverse(t.begin(), t.end());
if (mp.count(t) && mp[t] != i){
ans.push_back(vector<int>{
i, mp[t]});
}
}
if (j && isHuiWen(words[i], 0, j-1)){
string t = words[i].substr(j, m);
reverse(t.begin(), t.end());
if (mp.count(t) && mp[t] != i){
ans.push_back(vector<int>{
mp[t], i});
}
}
}
}
return ans;
}
};