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 1:
Given words
= ["bat", "tab", "cat"]
Return [[0, 1], [1, 0]]
The palindromes are ["battab", "tabbat"]
Example 2:
Given words
= ["abcd", "dcba", "lls", "s", "sssll"]
Return [[0, 1], [1, 0], [3, 2], [2, 4]]
The palindromes are ["dcbaabcd", "abcddcba", "slls", "llssssll"]
Difficulty: Hard
Solution: Use Trie.
public class Solution {
Node root = new Node();
public void insert(String s, int index){
Node curr = root;
for(int i = s.length() - 1; i >= 0; i--){
if(curr.next[s.charAt(i)- 'a'] == null){
curr.next[s.charAt(i)- 'a'] = new Node();
}
if(isPal(s ,0, i)){
curr.list.add(index);
}
curr = curr.next[s.charAt(i)- 'a'];
}
curr.list.add(index);
curr.index = index;
}
public void search(String[] words, int i, List<List<Integer>> list) {
Node curr = root;
for (int j = 0; j < words[i].length(); j++) {
if (curr.index >= 0 && curr.index != i && isPal(words[i], j, words[i].length() - 1)) {
list.add(Arrays.asList(i, curr.index));
}
curr = curr.next[words[i].charAt(j) - 'a'];
if (curr == null) return;
}
for (int j : curr.list) {
if (i == j) continue;
list.add(Arrays.asList(i, j));
}
}
public boolean isPal(String word, int i, int j){
while (i < j) {
if (word.charAt(i++) != word.charAt(j--)) return false;
}
return true;
}
public List<List<Integer>> palindromePairs(String[] words) {
List<List<Integer>> res = new ArrayList<>();
for (int i = 0; i < words.length; i++) {
insert(words[i],i);
}
for (int i = 0; i < words.length; i++) {
search(words, i, res);
}
return res;
}
}
class Node{
int index;
List<Integer> list;
Node[] next;
Node(){
index = -1;
next = new Node[26];
list = new ArrayList<Integer>();
}
}