class LRUCache {
constructor(capacity) {
this.capacity = capacity;
this.cache = {};
this.keys = [];
};
get(key) {
// if value is already in the cache,
// reorder keys array and put the key on the end of queue
let val = this.cache[key];
if (val !== undefined) {
this.keys.splice(this.keys.indexOf(key), 1);
this.keys.push(key);
return val;
}
return -1;
};
put(key, value) {
let obj = this.cache[key];
// if key is already in the cache
// remove key so we can add it on the end later
if (obj !== undefined) {
this.keys.splice(this.keys.indexOf(key), 1);
}
// if adding key is already over the capacity
// we are going to remove the first item on the keys
if (obj === undefined && this.keys.length === this.capacity) {
const oldKey = this.keys.shift(); //?
delete this.cache[oldKey]; //?
}
// add key to the keys, this is either an existing key or a new key
this.keys.push(key); //?
this.cache[key] = value;
}
Tag: leetcode
let reorderLogFiles = function(logs) {
let alpha = [],
numbers = [];
const isNumber = (str) => {
const [, content] = str.split(' ');
return content.match(/\d+/);
}
const getBody = (str) => {
return str.substring(str.indexOf(' ') + 1);
}
// separate alpha from numbers
logs.forEach(log => {
if (isNumber(log)) {
numbers.push(log);
}
else {
alpha.push(log);
}
});
let comparator = (x, y) => {
let compareResult = getBody(x).localeCompare(getBody(y));
if (compareResult === 0) {
return x.localeCompare(y);
}
return compareResult;
}
return [...alpha.sort(comparator), ...numbers];
};
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; };
Categories
Decode String
let decodeString = function(str) {
if (str.indexOf("[") < 0) {
return str;
}
let openingIndex = [];
let newStr = "";
for (let i = 0; i < str.length; i++) {
if (str[i] === "[") {
openingIndex.push(i);
newStr += str[i];
}
else if (str[i] === "]") {
let opening = openingIndex.pop();
let allMultipliers = str.substring(0, opening).match(/\d+/g);
let multiplier = allMultipliers[allMultipliers.length - 1];
let data = str.substring(opening + 1, i);
if (data.indexOf("[") < 0) {
newStr = newStr.substring(0, newStr.lastIndexOf("[") - multiplier.length) + data.repeat(multiplier);
console.log({opening, multiplier, data, newStr});
}
else {
newStr += str[i];
}
}
else {
newStr += str[i];
}
}
return decodeString(newStr);
};
Categories
LinkedList Middle Node
let middleNode = function(head) { let slow = head, fast = head; while (fast) { if (fast.next !== null && fast.next.next !== null) { slow = slow.next; fast = fast.next.next; } else if (fast.next) { slow = slow.next; break; } else { break; } } return slow; };
Categories
Reverse Middle of LinkedList
// m = start of items to reverse, n = end of item to reverse let reverseBetween = function(head, m, n) { let node = head, result = [], reversed = [], counter = 1; while (node) { let next = node.next; if (counter < m) { result.push(node); //? } if (counter >=m && counter <= n) { node.next = null; reversed.push(node); //? } else if (counter > n) { // all reversals are done // drain reversed into result while (reversed.length) { result.push(reversed.pop()); //? } result.push(node); break; } counter++; node = next; } // if reversals are done at the end of the linkedlist while (reversed.length) { result.push(reversed.pop()); //? } let root = new ListNode(0), tail = root; while (result.length) { tail.next = result.shift(); tail = tail.next; console.log(tail); } return root.next; //? };
Categories
Reverse LinkedList (Iterative)
let reverseLinkedList = function(root) { let reverse = new ListNode(0); let node = root; while (node) { let toAdd = node; let next = node.next; let reversedNext = reverse.next; toAdd.next = reversedNext; reverse.next = toAdd; // node = next; } return reverse.next; }
let reverseLinkedList = function(root, reverse = new ListNode(0)) {
if (root) {
let toAdd = root;
let next = root.next;
let reversedNext = reverse.next;
toAdd.next = reversedNext;
reverse.next = toAdd;
reverseLinkedList(next, reverse);
}
return reverse.next;
}
function fib(x) { let cache = {} function fibInternal(n) { if(n == 0) return 0; if(n <= 2) return 1; if (cache[n]) return cache[n]; const result = fibInternal(n - 1) + fibInternal(n - 2); cache[n] = result; return result; } return fibInternal(x) }
let intToRoman = function(num) { const mapping = { 1000: 'M', 900: 'CM', 500: 'D', 400: 'CD', 100: 'C', 90: 'XC', 50: 'L', 40: 'XL', 10: 'X', 9: 'IX', 5: 'V', 4: 'IV', 1: 'I' } let result = ""; for(let divisor of [1000, 900, 500, 400, 100, 90, 50, 40, 10, 9, 5, 4, 1]) { if (num >= divisor) { let quotient = Math.floor(num / divisor); result = result + mapping[divisor].repeat(quotient); num = num % divisor; } } return result; }