/**
* @param {number[]} inp
* @return {number}
*/
const largestRectangleArea = function(inp) {
const s = [];
let i = 0;
let max = 0;
while (i < inp.length) {
const val = inp[i];
if (!s.length || val >= inp[s[s.length - 1]]) {
s.push(i++);
} else {
const top = s.pop();
max = Math.max(s.length ? (i - s[s.length - 1] - 1) * inp[top] : i * inp[top], max);
}
}
while (s.length) {
const top = s.pop();
max = Math.max(s.length ? (i - s[s.length - 1] - 1) * inp[top] : i * inp[top], max);
}
return max;
};
Author: Shiva Charan Devabhaktuni
useMemo
and useCallback
are two React hooks that can help improve performance in your application by optimizing the rendering of your components.
useMemo
is used to memoize a value and only recalculate it when one of its dependencies changes. This is useful when you have a costly calculation that you don’t want to perform on every render. useMemo
takes two arguments: a function that returns the value to be memoized, and an array of dependencies. The value returned by the function will only be recalculated when one of the dependencies changes.
const memoizedValue = useMemo(() => {
// perform a costly calculation
return result;
}, [dependency1, dependency2]);
useCallback
is similar to useMemo
, but it is used to memoize a function instead of a value. This is useful when you have a function that you want to pass down to child components as a prop, but you don’t want it to be re-created on every render. useCallback
takes two arguments: a function, and an array of dependencies. The function returned by useCallback
will only be re-created when one of the dependencies changes.
const memoizedFunction = useCallback((arg1, arg2) => {
// perform some logic
}, [dependency1, dependency2]);
In general, you should use useMemo
to memoize a value and useCallback
to memoize a function. However, if you have a function that returns a value, you can use useMemo
instead of useCallback
.
In JavaScript, when handling an event in the browser, there are two different ways to access the event target: event.currentTarget
and event.target
.
event.target
refers to the element on which the event was originally triggered. This may be the element that was clicked on or interacted with by the user.
event.currentTarget
refers to the element that the event listener is attached to. This may be the parent element or some other ancestor of the element that was clicked on.
Here’s an example to illustrate the difference between event.target
and event.currentTarget
:
<body>
<div class="parent">
<button class="child">Click me</button>
</div>
</body>
<script>
const parent = document.querySelector('.parent');
const child = document.querySelector('.child');
parent.addEventListener('click', function(event) {
console.log(`Current target: ${event.currentTarget.tagName}`);
console.log(`Target: ${event.target.tagName}`);
});
child.addEventListener('click', function(event) {
console.log(`Current target: ${event.currentTarget.tagName}`);
console.log(`Target: ${event.target.tagName}`);
});
</script>
In this example, we have a parent element with a child element inside it. We attach a click event listener to both the parent and child elements.
When we click on the child element, the event listener attached to the child element is triggered first. In this case, the current target and target are both the child element.
Next, the event listener attached to the parent element is triggered because the click event bubbles up from the child element to its parent. In this case, the current target is the parent element (because that’s where the event listener is attached), but the target is still the child element (because that’s where the click event originated).
So, in summary, event.currentTarget
refers to the element that the event listener is attached to, while event.target
refers to the element on which the event was originally triggered.
Valid Sudoku
A valid Sudoku is a 9×9 grid puzzle where each row, column, and 3×3 subgrid contains the numbers 1 to 9 exactly once. Here is an example of a valid Sudoku:
5 3 4 | 6 7 8 | 9 1 2
6 7 2 | 1 9 5 | 3 4 8
1 9 8 | 3 4 2 | 5 6 7
---------------------
8 5 9 | 7 6 1 | 4 2 3
4 2 6 | 8 5 3 | 7 9 1
7 1 3 | 9 2 4 | 8 5 6
---------------------
9 6 1 | 5 3 7 | 2 8 4
2 8 7 | 4 1 9 | 6 3 5
3 4 5 | 2 8 6 | 1 7 9
/**
* @param {character[][]} board
* @return {boolean}
*/
var isValidSudoku = function(board) {
if (!board) {
return false;
}
const rowArr = [...Array(9)].map(x => new Object());
const colArr = [...Array(9)].map(x => new Object());
const boxObj = {};
for (let i = 0; i < 9; i++) {
let boxRow = 3 * Math.floor(i / 3) + '.';
for (let j = 0; j < 9; j++) {
let c = board[i][j];
if (c !== '.') {
if (c in rowArr[i]) {
return false;
} else {
rowArr[i][c] = true;
}
if (c in colArr[j]) {
return false;
} else {
colArr[j][c] = true;
}
const boxKey = boxRow + (3 * Math.floor(j / 3));
if (!(boxKey in boxObj)) {
boxObj[boxKey] = {};
}
if (c in boxObj[boxKey]) {
return false;
} else {
boxObj[boxKey][c] = true;
}
}
}
}
return true;
}
/**
* @param {character[][]} board
* @return {boolean}
*/
// var isValidSudoku = function(board) {
// if (!board) {
// return false;
// }
// for (let i = 0; i < board.length; i++) {
// for (let j = 0; j < board[0].length; j++) {
// const c = board[i][j];
// if ( c!== '.' && !valid(c, i , j, board)) {
// return false;
// }
// }
// }
// return true;
// };
// var valid = function(c, i, j, board) {
// const rowStart = 3 * Math.floor(i / 3);
// const colStart = 3 * Math.floor(j / 3);
// for (let k = 0; k < 9; k++) {
// if ((k !== j && board[i][k] === c) || (k !== i && board[k][j] === c)) {
// return false;
// }
// let row = rowStart + Math.floor(k / 3);
// let col = colStart + (k % 3);
// if (!(row === i && col === j) && c === board[row][col]) {
// return false;
// }
// }
// return true;
// }
Array.map() Polyfill
Array.prototype.map = function(callback, context) {
const ret = [];
for (let index = 0; index < this.length; index++) {
ret.push(callback.call(context, this[index], index, this));
}
return ret;
};
console.log([5, 4, 2].map((x, y) => {
console.log(x, y);
return 2 * x;
}));
/*
5, 0
4, 1
2, 2
[10, 8, 4]
*/
Matrix Chain Multiplication
const matrixChainMultiplication = (matrix, n) => {
const dp = Array(100).fill(0).map(x => Array(100).fill(-1));
// Ai Matrix dimensions = (i - 1) x (i)
return MCM(matrix, 1, n - 1, dp);
};
const MCM = (matrix, i, j, dp) => {
if (i === j) {
return 0;
}
if (dp[i][j] !== -1) {
return dp[i][j];
}
dp[i][j] = Number.MAX_VALUE;
for (let k = i; k < j; k++) {
dp[i][j] = Math.min(dp[i][j],
MCM(matrix, i, k, dp) + MCM(matrix, k + 1, j, dp) + (matrix[i - 1] * matrix[k] * matrix[j]));
}
return dp[i][j];
};
const test = [1, 2, 3, 4, 3];
console.log(matrixChainMultiplication(test, test.length)); // 30
Spiral Matrix
/**
* @param {number[][]} matrix
* @return {number[]}
*/
const spiralOrder = function(matrix) {
const list = [];
let r1 = 0;
let r2 = matrix.length - 1;
let c1 = 0;
let c2 = matrix[0].length - 1;
while (c1 <= c2 && r1 <= r2) {
for (let c = c1; c <= c2; c++)
list.push(matrix[r1][c]);
for (let r = r1 + 1; r <= r2; r++)
list.push(matrix[r][c2]);
if (r1 < r2 && c1 < c2) {
for (let c = c2 - 1; c > c1; c--)
list.push(matrix[r2][c]);
for (let r = r2; r > r1; r--)
list.push(matrix[r][c1]);
}
r1++;
r2--;
c1++;
c2--;
}
return list;
};
Best time to buy and sell stock
/**
* @param {number[]} prices
* @return {number}
*/
const maxProfit = function(prices) {
let min = prices[0];
let max = 0;
for (const price of prices) {
min = Math.min(min, price);
max = Math.max(max, price - min);
}
return max;
};
console.log(maxProfit([7, 1, 5, 3, 6, 4])); // 5
n = size of input array
Time complexity: O(n)
Space complexity: O(1)
Container With Most Water
/**
* @param {number[]} height
* @return {number}
*/
const maxArea = (height) => {
let low = 0;
let high = height.length - 1;
let max = 0;
while (low < high) {
max = Math.max(max, (high - low) * Math.min(height[low], height[high]));
if (height[low] <= height[high]) {
low++
} else {
high--;
}
}
return max;
};
console.log(maxArea([1, 8, 6, 2, 5, 4, 8, 3, 7])); // 49
Group Anagrams
Group Permutations of the same strings in a given list in Javascript:
/**
* @param {string[]} strs
* @return {string[][]}
*/
const groupAnagrams = function(strs) {
const obj = {};
for (const str of strs) {
const key = str.split('').sort().join('');
(obj[key] || (obj[key] = [])).push(str);
}
return Object.values(obj);
};
console.log(groupAnagrams(['abc', 'bbc', 'cab', 'ccc']));
// [["abc", "cab"], ["bbc"], ["ccc"]]