问题描述:
Given a list of unique words, return all the pairs of the distinct indices (i, j)
in the given list, so that the concatenation of the two words words[i] + words[j]
is a palindrome.
Example 1:
Input: words = ["abcd","dcba","lls","s","sssll"]
Output: [[0,1],[1,0],[3,2],[2,4]]
Explanation: The palindromes are ["dcbaabcd","abcddcba","slls","llssssll"]
Example 2:
Input: words = ["bat","tab","cat"]
Output: [[0,1],[1,0]]
Explanation: The palindromes are ["battab","tabbat"]
Example 3:
Input: words = ["a",""]
Output: [[0,1],[1,0]]
Constraints:
1 <= words.length <= 5000
0 <= words[i].length <= 300
words[i]
consists of lower-case English letters.
源码:
害,这两月忙了点别的事情,一直就没刷题了,这下手感生疏的很,想了半天也没啥思路,解法二就是我们瞎想的。
解法1:
需要借助一个特性,之前还不知道,就是set他会自动排序,把小的放在前面,大的放在后面。
- 首先用map存储每个字符串的位置,用set存储出现过的字符串大小;
- 对于每个字符串处理的步骤主要包括以下部分:
- 反转字符串,若反转后的字符串若在map中且位置不是自身,就加入result;
- 查找比字符串长度小的字符串能否和本串拼接,此时需要满足前半部分或者后半部分的反转能够找到,且剩余部分自身为回文;
- 若字符串前半部分是回文,后半部分的反转值可以在map中找到,则可以加入result;
- 同理若字符串前半部分是回文,后半部分的反转值可以在map中找到,则可以加入result;
class Solution {
private:
bool isvalid (string str, int begin, int end) {
while (begin < end) {
if (str[begin++] != str[end--]) {
return false;
}
}
return true;
}
public:
vector<vector<int>> palindromePairs(vector<string>& words) {
vector<vector<int>> result;
if (words.size() == 0) {
return result;
}
map<string, int> store;
set<int> lenSet;
for (int i=0; i<words.size(); i++) {
store[words[i]] = i;
lenSet.insert(words[i].length());
}
for (int i=0; i<words.size(); i++) {
string tmp = words[i];
int len = tmp.size();
reverse(tmp.begin(), tmp.end());
if (store.count(tmp) && store[tmp]!=i) {
result.push_back(vector<int> {i, store[tmp]});
}
auto endFlag = lenSet.find(len);
for (auto it=lenSet.begin(); it!=endFlag; it++) {
int d = *it;
if (isvalid(tmp, 0, len-d-1) && store.count(tmp.substr(len-d))) {
result.push_back(vector<int> {i, store[tmp.substr(len-d)]});
}
if (isvalid(tmp, d, len-1) && store.count(tmp.substr(0, d))) {
result.push_back(vector<int> {store[tmp.substr(0, d)], i});
}
}
}
return result;
}
};
解法2:失败
相当于暴力的做法,只是如果验证words[i]+words[j]是回文,只要words[i]和words[j]长度相等,则words[j]+words[i]也是回文。最终超时。
class Solution {
private:
bool isPail(string first, string second) {
string newStr = first+second;
int left=0, right=newStr.length()-1;
while (left < right) {
if (newStr[left] != newStr[right]) {
return false;
}
left++;
right--;
}
return true;
}
public:
vector<vector<int>> palindromePairs(vector<string>& words) {
vector<vector<int>> result;
if (words.size() == 0) {
return result;
}
set<pair<int,int>> store;
for (int i=0; i<words.size(); i++) {
for (int j=0; j<words.size(); j++) {
if (i == j || store.count(make_pair(i, j))) {
continue;
}
if (isPail(words[i], words[j])) {
result.push_back(vector<int>{i, j});
store.insert(make_pair(i, j));
if (words[i].length() == words[j].length()) {
result.push_back(vector<int>{j, i});
store.insert(make_pair(j, i));
}
}
}
}
return result;
}
};