Categories
Breadth First Search Leetcode Recursion Trie

Search Suggestion System (Trie)

let suggestedProducts = function(products, searchWord) {
const MAX_RESULT_COUNT = 3;
let root = {
children: {}
};

function addToNode(word, index, node) {
if (index >= word.length) {
node.end = true;
return;
}
//
const child = node.children[word[index]];
if (child) {
addToNode(word, index + 1, child);
}
else {
let child = {val: word[index], parent: node, children: {}};
node.children[word[index]] = child;
addToNode(word, index + 1, child);
}
}

function getWord(leaf) {
let node = leaf;
let str = '';
while (node) {
if (node.val) str = node.val + str; //?
node = node.parent; //?
}

return str; //?
}

function searchProducts(searchString) {

let words = [];
let nodes = [...Object.entries(root.children)], len = searchString.length;
while (nodes.length) {

let currentNodeLength = nodes.length;
while (currentNodeLength > 0) {
currentNodeLength--;

const node = nodes.pop();
const [key, val] = node;
if (len > 0 && key === searchString[searchString.length - len]) {
nodes.unshift(...Object.entries(val.children));

if (len === 1 && val.end) {
words.push(getWord(val));
}
} else if (len <= 0) {
if (val.end) words.push(getWord(val));
nodes.unshift(...Object.entries(val.children));
}
}
len--;
}

return words.sort().slice(0, Math.min(MAX_RESULT_COUNT, words.length));
}

for(let product of products) {
addToNode(product, 0, root);
}


let result = [];
for (let i = 0; i < searchWord.length; i++) {
result.push(searchProducts(searchWord.substring(0, i + 1))); //?
}

return result; //?
};