Categories
Array Dynamic Programming Leetcode

Minimum Path Sum (Iterative)

let minPathSum = function(grid) {

    if(!grid || !grid.length) return 0;

    let maxRow = grid.length, maxCol = grid[0].length;
    
    for (let row = 0; row < maxRow;row++) {
        for (let col = 0; col < maxCol;col++) {
            console.log(row, col);
            if (row === 0) {
                grid[row][col] = grid[row][col] + (grid[row][col - 1] || 0);
            }
            else if (col === 0) {
                grid[row][col] = grid[row][col] + grid[row - 1][col];
            } else {
                grid[row][col] = Math.min(
                    grid[row][col] + grid[row - 1][col], // top
                    grid[row][col] + grid[row][col - 1] // left
                );
            }
        }
    }
    return grid[maxRow - 1][maxCol - 1];
};
Categories
Array Leetcode Loop

Two Sum Less Than K

let twoSumLessThanK = function(A, K) {
let max = -1, start = 0, end = A.length - 1;
A.sort((a, b) => b - a); //?

while (start < end) {
let sum = A[start] + A[end];
if (sum < K) {
max = Math.max(sum, max);
end--;
}
else {
start++;
}
}

return max;
};
Categories
Array Leetcode Loop String

Reorganize String

let reorganizeString = function(S) {
let chars = {}, max = 0;
for(let i = 0; i < S.length;i++) {
if (chars[S[i]]) {
chars[S[i]] = chars[S[i]] + 1;
max = Math.max(chars[S[i]], max);
}
else {
chars[S[i]] = 1;
}
}

console.log(max, Math.floor((S.length + 1) / 2));
if (max > (S.length + 1) / 2) {
return "";
}

let result = [], index = 0;
const keys = Object.keys(chars).sort((a, b) => chars[b] - chars[a]); //?
while (keys.length) { //?
const key = keys.shift(); //?
result[index] = key;

if (chars[key] - 1 > 0) {
chars[key] = chars[key] - 1;
keys.unshift(key); //?
}

index += 2; //?
if (index >= S.length) {
index = 1;
}
}

return result.join('');
};
Categories
Array Leetcode Loop

Prison After N Days

let  prisonAfterNDays = function(cells, N) {

let cache = {},
counter = 1,
cycle = false,
len = 8;
let dup = [...cells];

function getNextCycle(data) {
let lastCycle = data[1];
let cycleDays = counter - lastCycle;
console.log(lastCycle, cycleDays);
let nextCycle = N - ((N - lastCycle) % cycleDays); //?.
// let nextCycle = counter; //?
// while (nextCycle + counter < N) {
// nextCycle = nextCycle += cycleDays;
// }

return nextCycle; //?
}

while(counter <= N) {
let key = dup.join(''),
data = cache[key],
row = [];

if (data && !cycle) {
cycle = true;
counter = getNextCycle(data);
}

if (data) {
dup = data[0];
counter++; //?
}
else {
for (let i = 0; i < len; i++) {
row[i] = dup[i - 1] === dup[i + 1] ? 1 : 0;
}
cache[key] = [[...row], counter];
dup = cache[key][0];
counter++; //?
}
}

return dup;
};
Categories
Array Leetcode Loop Sort

Most Visited Website Pattern

let mostVisitedPattern = function(username, timestamp, website) {
    let map = new Map();
    for (let i = 0; i < username.length; i++) {
        if (map.has(username[i])) {
            map.get(username[i]).push([website[i], timestamp[i]]);
        }
        else {
            map.set(username[i], [[website[i], timestamp[i]]]);
        }
    }

    // get all possibilites
    let visitedPattern = {};
    let possibilityMap = new Map();
    for(let [user, visits] of map.entries()) {
        visitedPattern[user] = {};
        const value = visits.sort((a, b) => a[1] - b[1]).map(([a]) => a);

        if ( value.length < 3) continue;
        for (let i = 0; i < value.length - 2; i++) {
            for (let j = i + 1; j < value.length - 1; j++) {
                for (let k = j + 1; k < value.length; k++) {
                    let key = `${value[i]},${value[j]},${value[k]}`;
                    if(possibilityMap.has(key)) {
                        if(!visitedPattern[user][key]) {
                            possibilityMap.set(key, possibilityMap.get(key) + 1);
                            visitedPattern[user][key] = 1;
                        }
                    }
                    else {
                        possibilityMap.set(key, 1);
                        visitedPattern[user][key] = 1;
                    }
                }
            }
        }
    }

    const result = [...possibilityMap];
    return result.sort((a, b) => {
        if(a[1] < b[1]) {
            return 1;
        }
        else if (a[1] > b[1]) {
            return -1;
        }
        return a[0].localeCompare(b[0]);
    }).map(arr => arr[0]).shift().split(','); //?


    // result.pop(); //?
        // .map(arr => arr[0]).pop().split('|'); //?
};
Categories
Array Leetcode Sort

Search Suggestion System (Simple)

let suggestedProducts = function(products, searchWord) {
products.sort();

let result = [];
for(let i = 0; i < searchWord.length; i++) {
products = products.filter(p => p[i] === searchWord[i]);
result.push(products.slice(0, Math.min(3, products.length)));
}

return result; //?
};
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; //?
};
Categories
Array Binary Search Leetcode Recursion

Search Matrix

let searchMatrix = function(matrix, target) {
if(!matrix.length) return false;

function search(startRow, endRow, startCol, endCol) {
console.log(startRow, endRow, startCol, endCol);
let midRow = Math.floor((startRow + endRow) / 2); //?
let midCol = Math.floor((startCol + endCol) / 2); //?


if (startRow < endRow && startCol < endCol) {
const midValue = matrix[midRow][midCol]; //?
if(midValue === target) {
return true;
}
if (midValue < target) {
return search(midRow + 1, endRow, startCol, endCol)
|| search(startRow, endRow, midCol + 1, endCol);
}
else {
return search(startRow, midRow, startCol, endCol)
|| search(startRow, endRow, startCol, midCol);
}
}

return false;
}

return search(0, matrix.length, 0, matrix[0].length);
};
Categories
Array Leetcode String

Top K Frequent Words

let topKFrequent = function(words, k) {
let map = new Map();
words.forEach(word => {
if(map.has(word)) {
map.set(word, map.get(word) + 1);
}
else {
map.set(word, 1);
}
});

return [...map].sort((x, y) => {
const f1 = x[1], f2 = y[1]
if (f1 < f2) return 1;
if (f1 > f2) return -1;
return x[0].localeCompare(y[0]);
}).map(x => x[0]).slice(0, k);
};