O(n*k*k) time
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38
| class Solution { public: vector<vector<int>> palindromePairs(vector<string>& words) { int n = words.size(); unordered_map<string, int> m; for (int i = 0; i < n; ++i) { m[words[i]] = i; } vector<vector<int>> res; for (int i = 0; i < n; ++i) { for (int j = 0; j <= words[i].length(); ++j) { auto left = words[i].substr(0, j); auto right = words[i].substr(j); if (isValid(left)) { string t(rbegin(right), rend(right)); if (m.count(t) && m[t] != i) { res.push_back({m[t], i}); } } if (!right.empty() && isValid(right)) { string t(rbegin(left), rend(left)); if (m.count(t) && m[t] != i) { res.push_back({i, m[t]}); } } } } return res; }
bool isValid(const string &s) { int l = 0, r = s.length() - 1; while (l < r) { if (s[l++] != s[r--]) return false; } return true; } };
|
Trie版本O(n*k2)k是每个单词平均长度,n是单词个数
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67
| class Solution { public: vector<vector<int>> palindromePairs(vector<string>& words) { Trie t; int n = words.size(); for (int i = 0; i < n; ++i) { t.add(words, i); } vector<vector<int>> res; for (int i = 0; i < n; ++i) { for (auto idx : t.find(words[i])) { if (idx != i && isPalindrome(words[i] + words[idx])) { res.push_back({i, idx}); } } } return res; }
bool isPalindrome(const string &s) { int n = s.length(); int i = 0, j = n - 1; for (; i < j && s[i] == s[j]; ++i, --j); return i >= j; }
struct TrieNode { TrieNode() : idx(-1), children({nullptr}) {} TrieNode *children[26]; int idx; vector<int> indices; };
struct Trie { Trie() : root(new TrieNode()) {} void add(const vector<string> &words, int idx) { auto node = root; for (auto rit = words[idx].rbegin(); rit != words[idx].rend(); ++rit) { if (!node->children[*rit - 'a']) { node->children[*rit - 'a'] = new TrieNode(); } node->indices.push_back(idx); node = node->children[*rit - 'a']; } node->idx = idx; node->indices.push_back(idx); } vector<int> find(const string &s) { auto node = root; vector<int> res; for (const auto &c : s) { if (!node->children[c - 'a']) { res.insert(res.end(), node->indices.begin(), node->indices.end()); return res; } else { if (node->idx != -1) { res.push_back(node->idx); } node = node->children[c - 'a']; } } res.insert(res.end(), node->indices.begin(), node->indices.end()); return res; } TrieNode *root; }; };
|