这个问题需要我们判断给定的一系列字符串中,能够构成回文字符串的字符串对有哪些?那么一个经典思路就是采用暴力求解,两个循环撸出来。
暴力求解
vector<vector<int>> palindromePairs(vector<string>& words) {
vector<vector<int>> result;
for (int i = 0; i<words.size(); i++){
for (int j = 0; j < words.size(); j++){
if (j != i){
string tail = words[j];
string head = words[i];
head += tail;
// Determine whether string is palindrome
int found = 1;
if (head.empty())
found = -1;
else{
int len = head.length();
for (int k = 0; k < len / 2; k++){
if (head[k] != head[len - k - 1]){
found = 0;
break;
}
}
}
// Store the palindrome pair
if (found == 1){
result.push_back({ i, j });
}
}
}
}
return result;
}
不过这题难就难在会超时,所以一定要修改。一个新的思路是,对每个字符串与比它短的字符串进行首尾匹配,比它长的字符串可以进行一个交换,之后的思路还是一样的。一个例子,字符串“bbbbbbbbcasfsdfsd”,与比它短的字符串“dsf”匹配,匹配成功后对剩下的字符串“bbbbbbbbcasfsd”进行回文判断;当满足上面两个条件时,则返回回文对。
修改后的算法
vector<vector<int>> palindromePairs(vector<string>& words) {
vector<vector<int>> result;
vector<int> wordLength;
unordered_map<string, int> map;
for (int i = 0; i < words.size(); i++){
map[words[i]] = i;
wordLength.push_back(words[i].length());
}
for (int i = 0; i < words.size(); i++){
string str = words[i];
int length = str.length();
reverse(str.begin(), str.end());
// Find words of same length
if (map.count(str) && map[str] != i)
result.push_back({ i, map[str] });
// Deal with words of different length
sort(wordLength.begin(), wordLength.end());
vector<int>::iterator iter = find(wordLength.begin(), wordLength.end(), length);
for (vector<int>::iterator it = wordLength.begin(); it != iter; it++){
int shorterLength = *it;
// Forward matching
if (map.count(str.substr(0, shorterLength)))
if (isValid(str, shorterLength, length - 1))
result.push_back({ map[str.substr(0, shorterLength)], i });
// Backward matching
if (map.count(str.substr(length - shorterLength)))
if (isValid(str, 0, length - shorterLength - 1))
result.push_back({ i, map[str.substr(length - shorterLength)] });
}
}
return result;
}
这里可能用到了一个unordered_map,主要是解决题目假设:自身与自身不能形成回文对。但是很不幸,这个还是超时了…….0.0。后来网上看到了一个别人的解法,思路类似,但是由于它在存储短的字符串的长度时用了set(自动排序且自动去重),这就大大加快了算法计算速度。(我还是太年轻了= =)
最终提交版本
vector<vector<int>> palindromePairs(vector<string>& words) {
vector<vector<int>> res;
unordered_map<string, int> m;
set<int> s;
for (int i = 0; i < words.size(); ++i) {
m[words[i]] = i;
s.insert(words[i].size());
}
for (int i = 0; i < words.size(); ++i) {
string t = words[i];
int len = t.size();
reverse(t.begin(), t.end());
if (m.count(t) && m[t] != i) {
res.push_back({ i, m[t] });
}
auto a = s.find(len);
for (auto it = s.begin(); it != a; ++it) {
int d = *it;
if (isValid(t, 0, len - d - 1) && m.count(t.substr(len - d))) {
res.push_back({ i, m[t.substr(len - d)] });
}
if (isValid(t, d, len - 1) && m.count(t.substr(0, d))) {
res.push_back({ m[t.substr(0, d)], i });
}
}
}
return res;
}