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; //?
};
Category: Breadth First Search
Categories
Oranges Rotting
let orangesRotting = function(grid) {
const FRESH = 1,
ROTTEN = 2,
VISITED = -1;
let rotten = [],
totalFresh = 0,
totalEmpty = 0,
total = 0;
function getAdjacents(row, col) {
let result = [];
// check top
if (row > 0 && grid[row -1][col] === FRESH) {
grid[row -1][col] = VISITED;
result.push([row - 1, col]);
}
// check bottom
if (row < grid.length - 1 && grid[row + 1][col] === FRESH) {
grid[row +1][col] = VISITED;
result.push([row + 1, col]);
}
// check left;
if (col > 0 && grid[row][col - 1] === FRESH) {
grid[row][col - 1] = VISITED;
result.push([row, col - 1]);
}
// check right
if (col < grid[row].length - 1 && grid[row][col + 1] === FRESH) {
grid[row][col + 1] = VISITED;
result.push([row, col + 1]);
}
return result;
}
for (let i = 0; i < grid.length; i++) {
for (let j = 0; j < grid[i].length; j++) {
const data = grid[i][j];
if (data === ROTTEN) {
rotten.push(...getAdjacents(i, j));
}
else if (data === FRESH || data === VISITED) {
totalFresh++;
}
else {
totalEmpty++;
}
total++;
}
}
totalFresh -= rotten.length;
let minute = 0;
while (rotten.length) {
let len = rotten.length;
while (len --> 0) {
let point = rotten.pop();
let [row, col] = point;
grid[row][col] = ROTTEN;
rotten.unshift(...getAdjacents(row, col));
}
totalFresh -= rotten.length;
minute++;
}
if (total === totalEmpty) return 0;
let hasFreshOranges = totalFresh > 0;
if (hasFreshOranges) return -1;
return minute;
};
function levelOrderZigzag(root) {
let queue = [root], result = [], direction = 0;
function process(node) {
result.push(node.val); //?
}
while (queue.length) {
let level = [];
while(queue.length) {
const node = queue.pop();
process(node);
if (direction === 0) {
if (node.left) level.push(node.left);
if (node.right) level.push(node.right);
}
else {
if (node.right) level.push(node.right);
if (node.left) level.push(node.left);
}
}
direction ^= 1;
queue = level;
}
return result; //?
}
function levelOrder(root) {
let queue = [root], result = [];
function process(node) {
result.push(node.val);
}
while (queue.length) {
const node = queue.pop();
process(node);
if (node.left) queue.unshift(node.left);
if (node.right) queue.unshift(node.right);
}
return result; //?
}
Categories
Number of Islands
let numIslands = function(matrix) {
if (!matrix.length) return 0;
let land = 1, visited = 'X',
counter = 0,
maxRow = matrix.length - 1,
maxCol = matrix[0].length - 1;
function exploreAndMark(row, col) {
if (row < 0 || col < 0 || row > maxRow || col > maxCol) {
return;
}
if (matrix[row][col] === land) {
matrix[row][col] = visited;
// explore up
exploreAndMark(row - 1, col);
// explore down
exploreAndMark(row + 1, col);
// explore left
exploreAndMark(row, col - 1);
// explore right
exploreAndMark(row, col + 1);
}
}
for (let row = 0; row <= maxRow; row++) {
for (let col = 0; col <= maxCol; col++) {
if (matrix[row][col] === land) {
counter++;
exploreAndMark(row, col);
}
}
}
return counter;
}