题目
Given a list of unique words, find all pairs of distinct indices (i, j) in the given list, so that the concatenation of the two words, i.e. words[i] + words[j] is a palindrome.
Example:
Input: [“abcd”,“dcba”,“lls”,“s”,“sssll”]
Output: [[0,1],[1,0],[3,2],[2,4]]
Explanation: The palindromes are [“dcbaabcd”,“abcddcba”,“slls”,“llssssll”]
Input: [“bat”,“tab”,“cat”]
Output: [[0,1],[1,0]]
Explanation: The palindromes are [“battab”,“tabbat”]
我的想法
直接brute force对每种组合进行回文串判断复杂度太高了。感觉应该可以用5. Longest Palindromic Substring的suffix tree
解答
leetcode solution: Trie Tree
字典树的典型应用
文字理解、Java实现
class Solution {
public List<List<Integer>> palindromePairs(String[] words) {
List<List<Integer>> res = new ArrayList<>();
if (words == null || words.length == 0) {
return res;
}
TrieNode root = new TrieNode();
int n = words.length;
for (int i = 0; i < n; ++i) {
insert(root, words[i].toCharArray(), i);
}
for (int i = 0; i < n; ++i) {
search(root, words[i].toCharArray(), i, res);
}
return res;
}
private void search(TrieNode root, char[] w, int pos, List<List<Integer>> res) {
int i1 = 0;
int n = w.length;
for (int i = n - 1; i >= 0; --i) {
if (root.idx >= 0 && root.idx != pos && isPalindrome(w, 0, i)) {
List<Integer> list = new ArrayList<>();
list.add(root.idx);
list.add(pos);
res.add(list);
}
char c = w[i];
int idx = c - 'a';
if (root.kids[idx] == null) {
return;
} else {
root = root.kids[idx];
}
}
for (int num : root.toEndIsPalin) {
if (num == pos) {
continue;
}
List<Integer> list = new ArrayList<>();
list.add(num);
list.add(pos);
res.add(list);
}
}
private boolean isPalindrome(char[] c, int s, int e) {
while (s < e) {
if (c[s++] != c[e--]) {
return false;
}
}
return true;
}
private void insert(TrieNode root, char[] w, int pos) {
int n = w.length;
for (int i = 0; i < n; ++i) {
if (isPalindrome(w, i, n - 1)) {
root.toEndIsPalin.add(pos);
}
int idx = w[i] - 'a';
if (root.kids[idx] == null) {
root.kids[idx] = new TrieNode();
}
root = root.kids[idx];
}
root.toEndIsPalin.add(pos);
root.idx = pos;
}
private class TrieNode {
TrieNode[] kids;
int idx;
List<Integer> toEndIsPalin;
TrieNode() {
idx = -1;
kids = new TrieNode[26];
toEndIsPalin = new ArrayList<>();
}
}
}