# Ruby's Louvre

## leetcode 336. Palindrome Pairs

 function palindromePairs(words) {
var result = []
for (var i = 0; i < words.length; i++) {
for (var j = 0; j < words.length; j++) {
if (i == j) continue;
var s = words[i] + words[j];
if (isPalindrome(s)) {
result.push([i, j])
}
}
}
return result;
}

function isPalindrome(s) {
var head = 0, tail = s.length - 1;
return false;
}
tail--;
}
return true;
}



1.先把所有字符串放进哈希表里。

1. 然后对每个字符串遍历分成两边，就是abcbd就分成['', abcbd],[a,bcbd], [ab, cbd], [abc, bd], [abcb, d], [abcbd, ""]。然后应用于上面提到的那个匹配算法。

   function reverse(str) {
return str.split('').reverse().join('')
}

function palindromePairs(words) {
var res = [], hash = {}
if (words == null || words.length < 2) {
return res
}
var blank = false
for (let i = 0; i < words.length; i++) {
if (words[i] === '') {
blank = true
}
hash[reverse(words[i])] = i;
}

for (let i = 0; i < words.length; i++) {
var word = words[i]
if (blank && isPalindrome(word) && word !== '') {
res.push([hash[''], i])
}
for (var j = 0; j < word.length; j++) {
var left = word.substring(0, j);
var right = word.substring(j);
if (hash[left] != null && isPalindrome(right) && hash[left] !== i) {
res.push([i, hash[left]])
}
if (hash[right] != null && isPalindrome(left) && hash[right] !== i) {
res.push([hash[right], i])
}
}
}
return res;
}

function isPalindrome(s) {
var head = 0, tail = s.length - 1;
return false;
}
tail--;
}
return true;
}


function Node(value) {
this.value = value
this.word = null
this.palindromes = []
this.children = new Array(26)
}
class Tire {
constructor() {
this.root = new Node(null)
}
seatchWord(){ }
}


   addWord(word, index) {
var node = this.root;
var word = reverse(word);
for (var i = 0; i < word.length; i++) {
if (isPalindrome(word.substring(i))) {
node.palindromes.push(index)
}
var next = word.charCodeAt(i) - 97
if (!node.children[next]) {
node.children[next] = new Node()
}
node = node.children[next]
}
node.word = word
node.index = index;
}


searchWord(word, index, res) {
var node = this.root;
for (var i = 0; i < word.length && node; i++) {
if (node.index != null && isPalindrome(word.substring(i)) && node.index !== index) {
res.push([index, node.index])
}
var next = word.charCodeAt(i) - 97;
node = node.children[next]
}
if (node) {
if (node.index != null && node.index !== index) {
res.push([index, node.index])
}
if (node.palindromes.length) {
for (let rightIndex of node.palindromes) {
res.push([index, rightIndex])
}
}
}
}



1. 当前节点index非空。这就表示str在当前节点上在已经走过了一个完整的单词。此时所需要判断的就是如果str剩下的部分是一个palindrome的话，那么str和该节点对应的index的单词就可以合并成为一个palindrome。当然你需要判断str所在的位置和index不是同一个位置即可。举个例子，如果你有一个word是abc，那么它在树里对应的分支就是c -> b -> a （因为是反向的树），如果str是cbaaba，那么它走到c - > b - > a的时候就会发现abc这个单词已经完结了，然后aba也是一个palindrome, 那么，cbaaba + abc就是cbaabaabc也是一个palindrome。

2. 当前节点的palindromes非空，也就是在这个节点有最少一个单词剩余的substring部分是palindrome。如果此时str已经走完了，就表示这个节点所有的palindromes对应的index都可以和str配对。 举个例子，如果有单词dedabc，dabc，edeabc，这样在c->b->a这个branch的a节点上，palindromes链表会有三个index对应前面三个单词。这个时候如果str是"cba"的话，他就会走到这个节点上，然后和前面三个单词凑成palindrome。

function Node(value) {
this.value = value
this.word = null
this.palindromes = []
this.children = new Array(26)
}
class Tire {
constructor() {
this.root = new Node(null)
}
var node = this.root;
var word = reverse(word);
for (var i = 0; i < word.length; i++) {
if (isPalindrome(word.substring(i))) {
node.palindromes.push(index)
}
var next = word.charCodeAt(i) - 97
if (!node.children[next]) {
node.children[next] = new Node()
}
node = node.children[next]
}
node.word = word
node.index = index;
}
searchWord(word, index, res) {
var node = this.root;
for (var i = 0; i < word.length && node; i++) {
if (node.index != null && isPalindrome(word.substring(i)) && node.index !== index) {
res.push([index, node.index])
}
var next = word.charCodeAt(i) - 97;
node = node.children[next]
}
if (node) {
if (node.index != null && node.index !== index) {
res.push([index, node.index])
}
if (node.palindromes.length) {
for (let rightIndex of node.palindromes) {
res.push([index, rightIndex])
}
}
}
}
}

function reverse(str) {
return str.split('').reverse().join('')
}

function palindromePairs(words) {
var res = [], hash = {}
if (words == null || words.length < 2) {
return res
}
var tire = new Tire, res = []

for (let i = 0; i < words.length; i++) {
}

for (let i = 0; i < words.length; i++) {
tire.searchWord(words[i], i, res)
}
return res;
}

function isPalindrome(s) {
var head = 0, tail = s.length - 1;