Skip to content

Commit

Permalink
refactor: js - stack
Browse files Browse the repository at this point in the history
  • Loading branch information
aakhtar3 committed Sep 19, 2022
1 parent 9897759 commit df68adb
Show file tree
Hide file tree
Showing 7 changed files with 475 additions and 146 deletions.
68 changes: 57 additions & 11 deletions javascript/150-Evaluate-Reverse-Polish-Notation.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,71 @@
/** @const {!Object} */
const OPERATORS = {
/**
* https://leetcode.com/problems/evaluate-reverse-polish-notation
* Time O(N^2) | Space(1)
* @param {string[]} tokens
* @return {number}
*/
var evalRPN = function(tokens, index = 0) {
while (1 < tokens.length) {/* Time O(N) */
const isOperation = () => tokens[index] in OPERATORS;
while (!isOperation()) index++;/* Time O(N) */

const value = performOperation(tokens, index);

tokens[index] = value;
tokens.splice((index - 2), 2);/* Time O(N) */
index--;
}

return tokens[0];
};

var OPERATORS = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => Math.trunc(a / b),
};

var performOperation = (tokens, index) => {
const [ rightNum, leftNum ] = [ Number(tokens[index - 1]), Number(tokens[index - 2]) ]
const operation = OPERATORS[tokens[index]];

return operation(leftNum, rightNum);
}

/**
* https://leetcode.com/problems/evaluate-reverse-polish-notation
* Time O(N) | Space(N)
* @param {string[]} tokens
* @return {number}
*/
function evalRPN(tokens) {
const stack = [];
for (const token of tokens) {
if (token in OPERATORS) {
const rhs = stack.pop();
const lhs = stack.pop();
stack.push(OPERATORS[token](lhs, rhs));
} else {
stack.push(Number(token));
var evalRPN = function (tokens, stack = []) {
for (const char of tokens) {/* Time O(N) */
const isOperation = char in OPERATORS;
if (isOperation) {
const value = performOperation(char, stack);

stack.push(value); /* Space O(N) */

continue;
}

stack.push(Number(char)); /* Space O(N) */
}

return stack.pop();
}

var OPERATORS = {
'+': (a, b) => a + b,
'-': (a, b) => a - b,
'*': (a, b) => a * b,
'/': (a, b) => Math.trunc(a / b)
};

var performOperation = (char, stack) => {
const [ rightNum, leftNum ] = [ stack.pop(), stack.pop() ];
const operation = OPERATORS[char];

return operation(leftNum, rightNum);
}
105 changes: 74 additions & 31 deletions javascript/155-Min-Stack.js
Original file line number Diff line number Diff line change
@@ -1,59 +1,102 @@
//////////////////////////////////////////////////////////////////////////////
// Two Stacks
// Time: O(1)
// Space: O(n)
// This solution uses two stacks to save the total values and the minimum
// values. Per each new value if it is less than or equal to the current
// minimum it is pushed to both stacks. We save duplicate minimum values to
// avoid the conundrum of inquiring whether the minimum value can be removed
// (i.e. when the minimum value equals the top value can it be removed or are
// there duplicate values in the main stack).
//////////////////////////////////////////////////////////////////////////////

/**
* https://leetcode.com/problems/min-stack
* Time O(1) | Space O(N)
* Your MinStack object will be instantiated and called as such:
* var obj = new MinStack()
* obj.push(x)
* obj.pop()
* var param_3 = obj.top()
* var param_4 = obj.getMin()
*/
class MinStack {
/**
* @constructor
*/
constructor() {
this.mainStack = [];
constructor () {
this.stack = [];
this.minStack = [];
}

/**
* @param {number} val
* @return {void}
*/
push(val) {
this.mainStack.push(val);
if (
!this.minStack.length ||
val <= this.minStack[this.minStack.length - 1]
) {
this.minStack.push(val);
}
push (val, { minStack } = this) {
this.stack.push(val); /* Space O(N) */

const isMinEmpty = !minStack.length;
const hasNewMin = val <= this.top(minStack);
const canAddMin = isMinEmpty || hasNewMin;
if (canAddMin) minStack.push(val);/* Space O(N) */
}

/**
* @return {void}
*/
pop() {
const val = this.mainStack.pop();
if (val === this.minStack[this.minStack.length - 1]) {
this.minStack.pop();
}
pop ({ stack, minStack } = this) {
const top = stack.pop(); /* Time O(1) */

const canPopMin = top === this.getMin();
if (canPopMin) minStack.pop(); /* Time O(1) */
}

/**
* @param {Array}
* @return {number}
*/
top() {
return this.mainStack[this.mainStack.length - 1];
top (stack = this.stack) {
return stack.length
? stack[stack.length - 1] /* Time O(1) */
: null;
}

/**
* @return {number}
*/
getMin() {
return this.minStack[this.minStack.length - 1];
getMin (minStack = this.minStack) {
return this.top(minStack); /* Time O(1) */
}
}


/**
* https://leetcode.com/problems/min-stack
* Time O(1) | Space O(1)
* Your MinStack object will be instantiated and called as such:
* var obj = new MinStack()
* obj.push(x)
* obj.pop()
* var param_3 = obj.top()
* var param_4 = obj.getMin()
*/
class MinStack {
constructor () {
this.head = null
}

push (val) {
this.head = (!this.head) /* Space O(1) */
? new Node(val, val, null)
: new Node(val, Math.min(val, this.head.min), this.head);
}

pop () {
this.head = this.head.next;/* Time O(1) */
}

top () {
return this.head.val; /* Time O(1) */
}

getMin () {
return this.head.min; /* Time O(1) */
}
}

class Node {
constructor (val, min, next) {
this.val = val;
this.min = min;
this.next = next;
}
}
38 changes: 20 additions & 18 deletions javascript/20-Valid-Parentheses.js
Original file line number Diff line number Diff line change
@@ -1,25 +1,27 @@
/**
* https://leetcode.com/problems/valid-parentheses
* Time O(N) | Space O(N)
* @param {string} s
* @return {boolean}
*/
var isValid = function (s) {
if (!s) return false;
let closeMap = {
'}': '{',
']': '[',
')': '(',
};
let stack = [];
for (const str of s) {
if (str in closeMap) {
if (stack.length !== 0 && stack.at(-1) === closeMap[str]) {
stack.pop();
} else {
return false;
}
} else {
stack.push(str);
}
var isValid = function(s, stack = []) {
for (const bracket of s.split('')) {/* Time O(N) */
const isParenthesis = bracket === '(';
if (isParenthesis) stack.push(')'); /* Space O(N) */

const isCurlyBrace = bracket === '{';
if (isCurlyBrace) stack.push('}'); /* Space O(N) */

const isSquareBracket = bracket === '[';
if (isSquareBracket) stack.push(']');/* Space O(N) */

const isOpenBracket = isParenthesis || isCurlyBrace || isSquareBracket;
if (isOpenBracket) continue;

const isEmpty = !stack.length;
const isWrongPair = stack.pop() !== bracket;
const isInvalid = isEmpty || isWrongPair;
if (isInvalid) return false;
}
return stack.length === 0;
};
132 changes: 99 additions & 33 deletions javascript/22-Generate-Parentheses.js
Original file line number Diff line number Diff line change
@@ -1,33 +1,99 @@
/**
* https://leetcode.com/problems/generate-parentheses/
*
* @param {number} n
* @return {string[]}
*/
var generateParenthesis = function (n) {
const combinations = [];
const currentCombination = [];

function exploreParens(opensRemaining, closesAvailable) {
if (currentCombination.length == n * 2) {
combinations.push(currentCombination.join(''));
return;
}

if (opensRemaining) {
currentCombination.push('(');
exploreParens(opensRemaining - 1, closesAvailable + 1);
currentCombination.pop();
}

if (closesAvailable) {
currentCombination.push(')');
exploreParens(opensRemaining, closesAvailable - 1);
currentCombination.pop();
}
}

exploreParens(n, 0);

return combinations;
};
/**
* https://leetcode.com/problems/generate-parentheses
* Time O(((4^N) / (N * SQRT(N)))) | Space O(((4^N) / (N * SQRT(N))))
* Time O(2^N) | Space O(2^N)
* @param {number} n
* @return {string[]}
*/
var generateParenthesis = (n) => dfs(n);/* Time O(2^N) | Space O(2^N) */

const dfs = (n, combos = [], open = 0, close = 0, path = []) => {
const isBaseCase = path.length === (n * 2);
if (isBaseCase) {
combos.push(path.join(''));/* Space O(N + N) */

return combos;
}

const isOpen = open < n;
if (isOpen) backTrackOpen(n, combos, open, close, path); /* Time O(2^N) | Space O(2^N) */

const isClose = close < open;
if (isClose) backTrackClose(n, combos, open, close, path);/* Time O(2^N) | Space O(2^N) */

return combos;
}

const backTrackOpen = (n, combos, open, close, path) => {
path.push('('); /* | Space O(N) */
dfs(n, combos, (open + 1), close, path);/* Time O(2^N) | Space O(2^N) */
path.pop();
}

const backTrackClose = (n, combos, open, close, path) => {
path.push(')'); /* | Space O(N) */
dfs(n, combos, open, (close + 1), path);/* Time O(2^N) | Space O(2^N) */
path.pop();
}

/**
* https://leetcode.com/problems/generate-parentheses
* Time O(((4^N) / (N * SQRT(N)))) | Space O(((4^N) / (N * SQRT(N))))
* Time O(2^N) | Space O(2^N)
* @param {number} n
* @return {string[]}
*/
var generateParenthesis = (n) => bfs(n);/* Time O(2^N) | Space O(2^N) */

const bfs = (n, queue, combos = []) => {
const queue = new Queue([ ['', 0, 0] ]);

while (!queue.isEmpty()) {/* Time O(2^N) */
const [ str, open, close ] = queue.dequeue();

const isBaseCase = (open === n) && (close === n);
if (isBaseCase) {
combos.push(str); /* Space O(N) */

continue;
}

const isOpen = open < n;
if (isOpen) queue.enqueue([ (`${str}(`), (open + 1), close ]); /* Space O(2^N) */

const isClose = close < open;
if (isClose) queue.enqueue([ (`${str})`), open, (close + 1) ]);/* Space O(2^N) */
}

return combos;
}

/**
* https://leetcode.com/problems/generate-parentheses
* Time O(((4^N) / (N * SQRT(N)))) | Space O(((4^N) / (N * SQRT(N))))
* Time O(2^N) | Space O(2^N)
* @param {number} n
* @return {string[]}
*/
var generateParenthesis = (n, combos = []) => {
const isBaseCase = n === 0;
if (isBaseCase) {
combos.push(''); /* | Space O(N) */

return combos;
}

return closureNumber(n, combos);/* Time O(2^N) | Space O(2^N) */
}

const closureNumber = (n, combos) => {
for (let c = 0; c < n; c++) {/* Time O(N) */
for (const left of generateParenthesis(c)) { /* Time O(2^N) | Space O(2^N) */
for (const right of generateParenthesis(((n - 1) - c))) {/* Time O(2^N) | Space O(2^N) */
combos.push(`(${left})${right}`); /* | Space O(N) */
}
}
}

return combos
}
Loading

0 comments on commit df68adb

Please sign in to comment.