の336回文
リスト内の2つの単語、単語[I] +言葉[j]は、パリンドローム配列にスプライシングすることができるように、すべての異なるインデックス対(i、j)を見つけるために、単語の固有のセットを設定します。
例1:
入力:[ "ABCD"、 "DCBA "、 "LLS"、 "S"、 "sssll"]
出力:[[0,1]、[1,0]、[3,2]、[2,4]]
説明:パリンドローム配列にスプライシングすることができる[ "dcbaabcd"、 "abcddcba"であり 、 "SLLS"、 "llssssll"]
実施例2:
入力:[ "バット"、 "タブ "、 "猫"]
出力:[[0,1]、[1,0]]
説明:回文配列中にスプライシングされている[ "battab"、 "tabbat" ]
PS:
そのような他のストリングの存在など、文字列逆トライが構成されており、現在の文字列が辞書ツリー内に存在するか否かを判断するには、サブストリングの存在を証明し、文字列がミラーに等しく、サブストリングの平均長さがKの複雑さが定義されていますO(N * K ^ 2)
class Solution {
private static List<List<Integer>> ans = new ArrayList<>();
public List<List<Integer>> palindromePairs(String[] words) {
if (words == null || words.length == 0) {
return null;
}
ans = new ArrayList<>();
TrieNode root = new TrieNode();
for (int i = 0; i < words.length; i++) {
addWord(root, words[i], i);
}
for (int i = 0; i < words.length; i++) {
find(root, words[i], i);
}
return ans;
}
private static class TrieNode {
//当前字符串的数组位置,下游节点,以及能构成当前串or回文子串节点的数组位置集合
int index;
TrieNode[] next;
List<Integer> palindIndex;
public TrieNode() {
index = -1;
next = new TrieNode[26];
palindIndex = new ArrayList<>();
}
}
private static void addWord(TrieNode root, String word, int index) {
for (int i = word.length() - 1; i >= 0; i--) {
int ch = word.charAt(i) - 'a';
if (root.next[ch] == null) {
root.next[ch] = new TrieNode();
}
if (isPalindrome(word, 0, i)) {
root.palindIndex.add(index);
}
root = root.next[ch];
}
root.index = index;
root.palindIndex.add(index);
}
private static void find(TrieNode root, String word, int index) {
for (int i = 0; i < word.length(); i++) {
//待匹配串比字典树子串长,如asadcc匹配树上的asad
if (root.index != -1 && root.index != index && isPalindrome(word, i, word.length() - 1)) {
ans.add(Arrays.asList(index, root.index));
}
//System.out.println("root index:" + root.index);
if (root.next[word.charAt(i) - 'a'] == null) {
return;
}
root = root.next[word.charAt(i) - 'a'];
}
//待匹配串比字典树子串短,如asad匹配树上的asadcc
for (int i : root.palindIndex) {
if (i != index) {
ans.add(Arrays.asList(index, i));
}
}
}
private static boolean isPalindrome(String string, int l, int r) {
while (l < r) {
if (string.charAt(l++) != string.charAt(r--)) {
return false;
}
}
return true;
}
}