An open API service indexing awesome lists of open source software.

https://github.com/alishahusain/newt

๐Ÿธ pattern algorithms data structures in javascript pseudo code space time complexity and most common implementation of each algorithm and data structure ๐Ÿธ
https://github.com/alishahusain/newt

algorithms dijkstra-algorithm heap javascript tree

Last synced: 12 months ago
JSON representation

๐Ÿธ pattern algorithms data structures in javascript pseudo code space time complexity and most common implementation of each algorithm and data structure ๐Ÿธ

Awesome Lists containing this project

README

          

#

## 14 Patterns Algorithim

Uses: Symbol in Pattern

๐Ÿ“Œ = 1 Pointers



๐Ÿ“ฆ = 1 Heap



๐Ÿšฅ = 1 Array



๐Ÿฝ = 1 Stack

๐Ÿฆœ = 1 Queue

๐Ÿ—‚ = 1 Hash

โž• = 1 Counter

๐ŸŒฑ = 1 Node

๐ŸŽก = 1 Loop

๐Ÿ“ฑ = 1 Graph

๐Ÿ”— = 1 Linked List

๐Ÿชž = 1 Recursion

๐Ÿคนโ€โ™€๏ธ = 1 Swap


๐ŸชŸ Sliding Window : ๐Ÿ“Œ๐Ÿšฅ๐ŸŽก







โ“ SUBSTRING OR SUBARRAY FIND LONGEST OR SMALLEST CONTAIN CHARACTER


โฐ: O(n) ๐Ÿช: O(n)





๐Ÿฃ Maximum Sum Subarray of Size K, Longest Substring with K Distinct CharactersString Anagrams, No-repeat Substring, etc.






function findAvgSubArrays(K, arr) {
const result = [];
let windowSum = 0, windowStart = 0;
for (let winEnd = 0; winEnd < arr.length; winEnd++) {
windowSum += arr[winEnd];
if (winEnd >= K - 1) {
result.push(windowSum / K);
windowSum -= arr[windowStart];
windowStart += 1;
}
}
return result;
}




Sliding Window Pattern

๐ŸชŸ Problems


## [Longest Substring Without Repeating Characters](https://leetcode.com/problems/longest-substring-without-repeating-characters/) #3 ๐ŸชŸ
โ“: Given a string s, find the length of the longest substring without repeating characters.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "abcabcbb" Output: 3 Explain: The answer is "abc", with the length of 3. 2๏ธโƒฃ Input: s = "bbbbb" Output: 1 Explain: The answer is "b", with the length of 1. 3๏ธโƒฃ Input: s = "pwwkew" Output: 3 Explain: The answer is "wke", with the length of 3. Notice that the answer must be a substring, "pwke" is a subsequence & not a substring. #4 Input: s = "" Output: 0

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^3) ๐Ÿช: O(min(m, n))
๐Ÿ‡ Solution: ๐ŸชŸ Sliding Window Pattern โฐ: O(n) ๐Ÿช: O(n)

var lengthOfLongestSubstring = function (s) {
let result = 0;
let left = 0;
let right = 0;
let set = new Set();
while (right < s.length) {
if (!set.has(s[right])) {
set.add(s[right]);
right++;
result = Math.max(result, set.size);
} else {
set.delete(s[left]);
left++;
}
}
return result;
};
## [Longest Repeating Character Replacement](https://leetcode.com/problems/longest-repeating-character-replacement/) #424 ๐ŸชŸ
โ“: You are given a string s & an integer k. You can choose any character of the string & change it to any other uppercase English character. You can perform this operation at most k times.
Return the length of the longest substring containing the same letter you can get after performing the above operations.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "ABAB", k = 2 Output: 4 Explain: Replace the two 'A's with two 'B's or vice versa. 2๏ธโƒฃ Input: s = "AABABBA", k = 1 Output: 4 Explain: Replace the one 'A' in the middle with 'B' & form "AABBBBA". The substring "BBBB" has the longest repeating letters, which is 4.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^2) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐ŸชŸ Sliding Window Pattern โฐ: O(n) ๐Ÿช: O(n)

var characterReplacement = function (s, k) {
let left = 0;
let right = 0;
let maxCount = 0;
let map = new Map();
while (right < s.length) {
map.set(s[right], (map.get(s[right]) || 0) + 1);
maxCount = Math.max(maxCount, map.get(s[right]));
if (right - left + 1 - maxCount > k) {
map.set(s[left], map.get(s[left]) - 1);
left++;
}
right++;
}
return right - left;
};
## [Minimum Window Substring](https://leetcode.com/problems/minimum-window-substring/) #76 ๐ŸชŸ
โ“: Given two strings s & t of lengths m & n respectively, return the minimum window substring of s such that every character in t (including duplicates) is included in the window. If there is no such substring, return the empty string "".
The testcases will be generated such that the answer is unique.
A substring is a contiguous sequence of characters within the string.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "ADOBECODEBANC", t = "ABC" Output: "BANC" Explain: The minimum window substring "BANC" includes 'A', 'B', & 'C' from string t. 2๏ธโƒฃ Input: s = "a", t = "a" Output: "a" 3๏ธโƒฃ Input: s = "a", t = "aa" Output: "" Explain: Both 'a's from t must be included in the window. Since the largest window of s only has one 'a', return empty string.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^2) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐ŸชŸ Sliding Window Pattern โฐ: O(n) ๐Ÿช: O(n)

var minWindow = function (s, t) {
let left = 0;
let right = 0;
let map = new Map();
let min = Infinity;
let result = "";
for (let i = 0; i < t.length; i++) {
map.set(t[i], (map.get(t[i]) || 0) + 1);
}
let count = map.size;
while (right < s.length) {
let char = s[right];
if (map.has(char)) {
map.set(char, map.get(char) - 1);
if (map.get(char) === 0) {
count--;
}
}
right++;
while (count === 0) {
if (right - left < min) {
min = right - left;
result = s.substring(left, right);
}
let char = s[left];
if (map.has(char)) {
map.set(char, map.get(char) + 1);
if (map.get(char) > 0) {
count++;
}
}
left++;
}
}
return result;
};


๐Ÿ‘ฏ Two Pointers: ๐Ÿ“Œ๐Ÿ“Œ๐ŸŽก





โ“ FIND A PAIR, TRIPLET or a SUBARRAY


โฐ: O(n) ๐Ÿช: O(n)





๐Ÿฃ Squaring a Sorted Array, Triplets that Sum to Zero, Triplet Sum Close to Target, Triplets with Smaller Sum, Subarrays with Product Less than a Target, Comparing Strings containing Backspaces, etc.






left = 0;
right = 0;
while (right < s.length()) {
// add s[right] to window
right++;
while (window needs shrink) {
// remove s[left] from window
left++;
}
}




Two Pointers


๐Ÿฐ๐Ÿข Fast & Slow Pointers: ๐Ÿ“Œ๐Ÿ“Œ ๐ŸŽก





โ“ FIND CYCLE IN A LINKED LIST OR FIND THE MIDDLE OF A LINKED LIST


โฐ:โฐ: O(n) ๐Ÿช: O(n)




๐Ÿฃ Linked List Cycle, Palindrome LinkedList, Cycle in a Circular Array, etc.






๐ŸŽญ PsuendoCode




slow = 0;
fast = 0;
while (fast < s.length()) {
if (s[fast] is not a duplicate) {
// move slow pointer one step
// add s[fast] to window
slow++;
}
// move fast pointer one step
fast++;
}




Fast & Slow Pointers Pattern


๐Ÿš—๐Ÿš™ Merge Intervals : ๐Ÿ“Œ๐Ÿ“Œ๐Ÿšฅ





โ“ MERGE INTERVALS OR FIND OVERLAPPING INTERVALS


โฐ: O(nlogn) ๐Ÿช: O(n)





๐Ÿฃ Insert Interval, Intervals Intersection, Conflicting Appointments, Minimum Meeting Rooms, etc.




๐ŸŽญ PsuendoCode




function merge(intervals) {
if (intervals.length < 2) {
return intervals;
}
// sort the intervals on the start time
intervals.sort((a, b) => a[0] - b[0]);
const mergedIntervals = [];
let start = intervals[0][0],
end = intervals[0][1];
for (i = 1; i < intervals.length; i++) {
const interval = intervals[i];
if (interval[0] <= end) {
end = Math.max(interval[1], end);
} else {
mergedIntervals.push([start, end]);
start = interval[0];
end = interval[1];
}
}
// add the last interval
mergedIntervals.push([start, end]);
return mergedIntervals;
}




Merge Intervals Pattern


๐Ÿ๐Ÿ”š Mod Binary Search: ๐Ÿ“Œ๐Ÿ“Œ๐Ÿ“Œ๐ŸŽก





โ“ MINIMUM DIFFERENCE OR FIND ELEMENT IN INFINITE SORTED ARRAY




๐Ÿฃ Order-agnostic Binary Search, Ceiling of a Number, Floor of a Number, Next Letter, Number Range, etc.






๐ŸŽญ PsuendoCode ๐Ÿ๐Ÿ”š Mod Binary Search Pattern ๐Ÿ๐Ÿ”š




start = 0, end = arr.length - 1;
while (start <= end) {
// calculate the middle of the current range
mid = start + (end - star
if (key < arr[mid]) {
end = mid - 1; // the 'key' can be in the first half
} else if (key > arr[mid]) {
start = mid + 1; // the 'key' can be in the second half
} else { // found the key
return mid;
}
}
// element is not found
return -1;




๐ŸŒ€ Cyclic Sort : ๐ŸŽก๐Ÿคนโ€โ™€๏ธ







โ“ FIND MISSING # OR SORT #s IN PLACE


๐Ÿฃ Cyclic Sort, Find the Missing Number, Find all Missing Numbers,

Find the Duplicate Number, Find all Duplicate Numbers, Find the Corrupt Pair, etc.


โฐ: O(n) ๐Ÿช: O(1)


๐ŸŽญ PsuendoCode



i = 0;
while (i < nums.length) {
j = nums[i] - 1;
if (nums[i] != nums[j])
swap(nums, i, j); // put the number in its correct place
else
i++;
}




Cyclic Sort Pattern

๐Ÿ”€๐Ÿ”— Reverse LinkList : ๐ŸŒฑ๐Ÿคนโ€โ™€๏ธ๐ŸŽก








โ“ REVERSE A LINKEDLIST


โฐ: O(n) ๐Ÿช: O(1)




๐Ÿฃ Reverse a LinkedList, Reverse a Sub-list, Reverse every K-element Sub-list (medium), etc.






๐ŸŽญ PsuendoCode




function reverse(head) {
let prev = null;
while (head !== null) {
next = head.next;
head.next = prev;
prev = head;
head = next;
}
return prev;
}





๐ŸŒณ BFS : ๐Ÿฆœ ๐Ÿชž





โ“ FIND MIN DEPTH, MAX DEPTH, LEVEL AVERAGE OF BINARY TREE


โฐ: O(n) ๐Ÿช: O(n)




๐Ÿฃ Level Order Traversal, Zigzag Traversal, Level Averages in a Binary Tree,

Minimum Depth of a Binary Tree, Level Order Successor,

Connect Level Order Siblings, etc. Tree Breadth First Search?






๐ŸŽญ PsuendoCode ๐ŸŒณ




const queue = [root];
while (queue.length) {
const currentNode = queue.shift();
if (currentNode.left) queue.push(currentNode.left);
if (currentNode.right) queue.push(currentNode.right);
}





๐ŸŒฒ DFS : ๐Ÿฝ๐Ÿชž





โ“ FIND PATH WITH MAX SUM OR PATH WITH GIVEN SEQUENCE


โฐ: O(n) ๐Ÿช: O(n)




๐Ÿฃ Reverse Level Order Traversal, Zigzag Traversal,

Level Averages in a Binary Tree, Minimum Depth of a Binary Tree,

Level Order Successor, Connect Level Order Siblings, etc.






๐ŸŽญ PsuendoCode Tree Depth First Search Pattern ๐ŸŒฒ




Stack< Tree Node stack = new Stack<>();
stack.push(root);
while (!stack.isEmpty()) {
TreeNode currentNode = stack.pop();
if (currentNode.left != null) stack.push(currentNode.left);
if (currentNode.right != null) stack.push(currentNode.right);
}





๐Ÿ“ฆ๐Ÿ“ฆ Two Heaps : ๐Ÿ“ฆ๐Ÿ“ฆ ๐ŸŽก





โ“ MEDIAN OF # STREAM FIND K SMALLEST #




๐Ÿฃ Sliding Window Median, Find the Median of a Number Stream, etc.






๐ŸŽญ PsuendoCode Two Heaps Pattern ๐Ÿ“ฆ๐Ÿ“ฆ




let maxHeap = new MaxHeap();
let minHeap = new MinHeap();
for (num of nums) {
if (maxHeap.isEmpty() || num <= maxHeap.peek()) {
maxHeap.push(num);
} else {
minHeap.push(num);
}
if (maxHeap.size() > minHeap.size() + 1) {
minHeap.push(maxHeap.pop());
} else if (maxHeap.size() < minHeap.size()) {
maxHeap.push(minHeap.pop());
}
}





๐Ÿ› Subsets : ๐Ÿšฅ๐ŸŽก







โ“ FIND ALL SUBSETS OF A SET OR FIND ALL SUBSETS ADD UP TO GIVEN #PERMUTATIONS AND COMBINATIONS OF SUBSETS




๐Ÿฃ Find all subsets of a set, Find all subsets of a set with duplicates, Find all subsets with a given sum, etc.






๐ŸŽญ PsuendoCode




let subsets = [[]];
for (let i = 0; i < nums.length; i++) {
let n = subsets.length;
for (let j = 0; j < n; j++) {
let set = subsets[j].slice(0);
set.push(nums[i]);
subsets.push(set);
}
}





#๏ธโƒฃ ๐Ÿ‘‘ K TOP : ๐Ÿ“ฆ ๐ŸŽก๐ŸŽก





โ“ TOP K #s OR FREQUENCY OF TOP K #s




๐Ÿฃ Top 'K' Numbers, Kth Largest Number in a Stream, K Closest Points to the Origin, etc.






๐ŸŽญ PsuendoCode K TOP in Javascript:




import MinHeap from './DataStructures/Heap/MinHeap.js';

function findLargestKNum(nums, k) {
const minHeap = new MinHeap();
for (i = 0; i < k; i++) {
minHeap.push(nums[i]);
}
for (i = k; i < nums.length; i++) {
if (nums[i] > minHeap.peek()) {
minHeap.pop();
minHeap.push(nums[i]);
}
}

return minHeap.toArray();
}





#๏ธโƒฃ๐Ÿš•๐Ÿš“ K MERGE : ๐ŸŒฑ๐Ÿ“ฆ๐ŸŽก๐ŸŽก





โ“ MERGE K SORTED ARRAYS OR MERGE K SORTED LISTS




๐Ÿฃ Merge K Sorted Lists, Kth Smallest Number in M Sorted Lists, Kth Smallest Number in a Sorted Matrix, etc.






๐ŸŽญ PsuendoCodeK MERGE Pattern in Javascript:




import ListNode from "DataStructures/LinkedList/ListNode.js";
import MinHeap from "DataStructures/Heaps/MinHeap.js";

const mergeKLists = function (lists) {
if (lists.length === 0) return null;
let dummy = new ListNode();
let curr = dummy;
let minHeap = new MinHeap();
for (let i = 0; i < lists.length; i++) {
if (lists[i]) minHeap.insert(lists[i]);
}
while (minHeap.size() > 0) {
let node = minHeap.remove();
curr.next = node;
curr = curr.next;
if (node.next) minHeap.insert(node.next);
}
return dummy.next;
};





๐Ÿ“… Topological Sort : ๐Ÿ“ฆ๐Ÿ“ฑ๐ŸŽก







โ“ FIND ORDER OF TASKS OR IF GIVEN SEQUENCE IS VALID




Topological Sort: Definition




๐Ÿฃ Tasks Scheduling, Tasks Scheduling Order, All Tasks Scheduling Orders, etc.




๐ŸŽญ PsuendoCode ๐Ÿ“… Topological Sort Pattern ๐Ÿ“… in Javascript:




const Deque = require('collections/deque'); //http://www.collectionsjs
function print_orders(tasks, prerequisites) {
sortedOrder = [];
if (tasks <= 0) {
return false;

// a. Initialize the graph
inDegree = Array(tasks).fill(0); // count of incoming edges
graph = Array(tasks).fill(0).map(() => Array()); // adjacency list g
// b. Build the graph
prerequisites.forEach((prerequisite) => {
let parent = prerequisite[0],
child = prerequisite[1];
graph[parent].push(child); // put the child into it's parent's list
inDegree[child]++; // increment child's inDegree

// c. Find all sources i.e., all vertices with 0 in-degrees
sources = new Deque();
for (i = 0; i < inDegree.length; i++) {
if (inDegree[i] === 0) {
sources.push(i);
}

print_all_topological_sorts(graph, inDegree, sources, sortedOrder);
return sortedOrder;

function print_all_topological_sorts(graph, inDegree, sources, sortedOrder) {
if (sources.length > 0) {
for (i = 0; i < sources.length; i++) {
vertex = sources.shift();
sortedOrder.push(vertex);
sourcesForNextCall = sources.slice(0); // make a copy of sources
// only remove the edges, if all of its children are not sources
graph[vertex].forEach((child) => { // get the node's children to decrement their in-degrees
inDegree[child]--; // decrement inDegree of child
if (inDegree[child] === 0) {
sourcesForNextCall.push(child); // save the new source for the next call
}
});
// recursive call to print other orderings from the remaining (and new) sources
print_all_topological_sorts(graph, inDegree, sourcesForNextCall, sortedOrder);
// backtrack, remove the vertex from the sorted order and put all of its children back to consider
// the next source instead of the current vertex
sortedOrder



## Other Patterns

## Union Find Algorithm Pattern โ™พ ->
โ“ # OF CONNECTED COMPONENETS IN UNDIRECTED GRAPH, FIND IF 2 NODES CONNECTED
๐Ÿฃ Number of Connected Components in an Undirected Graph, Find whether two nodes are connected in an undirected graph, etc.

๐ŸŽญ PsuendoCode Union Find Algorithm Pattern โ™พ
โฐ: O(V * logV) ๐Ÿช: O
function find(int[] parent, i) {
if (parent[i] == -1) return i;
return find(parent, parent[i]);

function union(int[] parent, x, y) {
xset = find(parent, x);
yset = find(parent, y);
parent[xset] = yset;
}
## Greedy Pattern ๐Ÿ’ฐ ->
โ“ MINIMUM # OF MEETINGS MAX OF INTERVALS NOT OVERLAPPING
๐Ÿฃ Activity Selection Problem, Coin Change, Fractional Knapsack Problem, Job Sequencing Problem, Huffman Coding, Prim's Minimum Spanning Tree, Kruskal's Minimum Spanning Tree, Dijkstra's Shortest Path Algorithm, Bellman-Ford Algorithm, Floyd-Warshall Algorithm, Travelling Salesman Problem

๐ŸŽญ PsuendoCode Greedy Pattern ๐Ÿ’ฐ
โฐ: O(nlogn) ๐Ÿช: O(1)

Arrays.sort(intervals, (a, b) -> Integer.compare(a[0], b[0]));
count = 0, end = Integer.MIN_VALUE;
for (int[] interval : intervals) {
if (interval[0] >= end) {
count++;
end = interval[1];
}
}
return count;
![alt text](https://www.quizzcreator.com/img/QUIZ/quiz/60b2236b8c9666.00493324.173.2077.jpg);
## Backtracking Pattern ๐ŸŽฒ ->
โ“ FIND ALL PERMUTATIONS COMBINATIONS SUBSETS PARTIONING
๐Ÿฃ N-Queens Problem, Sudoku Solver, Rat in a Maze, Knight's Tour Problem, Hamiltonian Cycle, Subset Sum Problem, Permutations, Combination Sum, Palindrome Partitioning, Word Break Problem, etc.

๐ŸŽญ PsuendoCode Backtracking Pattern ๐ŸŽฒ
โฐ: O(n!) ๐Ÿช: O(n)

function backtrack(n, ArrayList nums, List> output, first) {
// if all integers are used up
if (first == n)
output.add(new ArrayList(nums));
for (i = first; i < n; i++) {
// place i-th integer first
// in the current permutation
Collections.swap(nums, first, i);
// use next integers to complete the permutations
backtrack(n, nums, output, first + 1);
// backtrack
Collections.swap(nums, first, i);
}
![alt text](https://ibpublicimages.s3-us-west-2.amazonaws.com/tutorial/backtracking1.png);
## Dynamic Programming Pattern ๐Ÿ“ˆ ->
โ“ FIND OPTIMAL SOLUTION TO COMPLEX PROBLEMS MIN MAX OR COUNT OF GIVEN CONSTRAINTS
๐Ÿฃ Fibonacci Numbers, House Thief, Minimum Coin Change, House Painters, Palindromic Subsequence, Longest Common Subsequence, Longest Increasing Subsequence, Longest Common Substring, Edit Distance, 0/1 Knapsack Problem, Subset Sum Problem, Unbounded Knapsack Problem, Rod Cutting, Word Break Problem, etc.

๐ŸŽญ PsuendoCode Dynamic Programming Pattern ๐Ÿ“ˆ
โฐ: O(n) ๐Ÿช: O(n)

int[] dp = new int[n + 1];
dp[0] = 1;
dp[1] = 1;
for (i = 2; i <= n; i++)
dp[i] = dp[i - 1] + dp[i - 2];
return dp[n];
![alt text](https://imgs.developpaper.com/imgs/51946-20190827144809463-5507841.png);
## ๐Ÿงฉ Bit Manipulation Pattern ๐Ÿงฉ ->
1๏ธโƒฃ Bitwise XOR
โ“ FIND IF NUMBER IS POWER OF 2
๐Ÿฃ Power of 2, Bitwise AND of Numbers Range, etc.

๐ŸŽญ PsuendoCode ๐Ÿงฉ Bit Manipulation Pattern ๐Ÿงฉ
โฐ: O(1) ๐Ÿช: O(1)
return (n & (n - 1)) == 0;

โ“ FIND UNIQUE NUMBER IN ARRAY OF PAIRS
๐Ÿฃ Single Number, Find the Missing Number, Find the Duplicate Number, Find the Corrupt Pair, etc.
2๏ธโƒฃ Bitwise AND
๐ŸŽญ PsuendoCode Bitwise XOR Pattern ๐Ÿงฉ
โฐ: O(n) ๐Ÿช: O(1)
int n = nums.length;
for (i = 0; i < n; i++)
x1 = x1 ^ nums[i];
for (i = 1; i <= n + 1; i++)
x2 = x2 ^ i;
return x1 ^ x2;
3๏ธโƒฃ Bitwise OR
โ“ FIND IF NUMBER IS POWER OF 4
๐Ÿฃ Power of 4, etc.
๐ŸŽญ PsuendoCode Bitwise OR Pattern ๐Ÿงฉ
โฐ: O(1) ๐Ÿช: O(1)
return (n > 0) && ((n & (n - 1)) == 0) && ((n & 0xAAAAAAAA) == 0);

![alt text](https://miro.medium.com/max/620/1*CxPeaIX4QxILRzucksVCsw.png);

4๏ธโƒฃ Bitwise Left Shift
โ“ FIND IF NUMBER IS POWER OF 2
๐Ÿฃ Power of 2, etc.
๐ŸŽญ PsuendoCode Bitwise Left Shift Pattern ๐Ÿงฉ
โฐ: O(1) ๐Ÿช: O(1)
return (n > 0) && ((n & (n - 1)) == 0);

![alt text](https://cdn.educba.com/academy/wp-content/uploads/2020/05/Left-Shift-Operator-in-C-01.png);

5๏ธโƒฃ Bitwise Right Shift
โ“ FIND IF NUMBER IS POWER OF 2
๐Ÿฃ Power of 2, etc.
๐ŸŽญ PsuendoCode Bitwise Right Shift Pattern ๐Ÿงฉ
โฐ: O(1) ๐Ÿช: O(1)
return (n > 0) && ((n & (n - 1)) == 0);
![alt text](https://he-s3.s3.amazonaws.com/media/uploads/5f05f51.jpg);
## ๐Ÿ“ Matrix Pattern ๐Ÿ“ ->
โ“ FIND IF MATRIX IS SINGULAR
๐Ÿฃ Matrix Chain Multiplication, etc.

๐ŸŽญ PsuendoCode ๐Ÿ“ Matrix Pattern ๐Ÿ“
โฐ: O(n^3) ๐Ÿช: O(n^2)
int n = matrix.length;
for (i = 0; i < n; i++) {
if (matrix[i][i] == 0) {
boolean zeroRow = true;
for (j = 0; j < n; j++) {
if (matrix[i][j] != 0) {
zeroRow = false;
break;
}
}
if (zeroRow) return true;
boolean zeroColumn = true;
for (j = 0; j < n; j++) {
if (matrix[j][i] != 0) {
zeroColumn = false;
break;
}
}
if (zeroColumn) return true;
}
}
return false;
![alt text](https://www.geeksforgeeks.org/wp-content/uploads/strassen_new.png);
## ๐Ÿ“˜ Trie Pattern ๐Ÿ“˜ ->
โ“ FIND ALL WORDS WITH GIVEN PREFIX
๐Ÿฃ Word Search, Word Break Problem, etc.

๐ŸŽญ PsuendoCode ๐Ÿ“˜ Trie Pattern ๐Ÿ“˜
โฐ: O(n) ๐Ÿช: O(n)
TrieNode root = new TrieNode();
for (String word : words) {
TrieNode node = root;
for (char letter : word.toCharArray()) {
if (node.children[letter - 'a'] == null)
node.children[letter - 'a'] = new TrieNode();
node = node.children[letter - 'a'];
}
node.word = word;
}
return root;
![alt text](https://miro.medium.com/max/630/1*f89l46VKjKPgnecqOw4V_w.png);

# 75 BLIND CURATED LEETCODE QUESTIONS:
## Array
## [Two Sum](https://leetcode.com/problems/two-sum/) #1 ๐Ÿ‘ฏ
โ“: Given an array of integers nums & an integer target, return indices of the two numbers such that they add up to target.
๐Ÿฃ: Given nums = [2, 7, 11, 15], target = 9, Because nums[0] + nums[1] = 2 + 7 = 9, return [0, 1].

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N^2) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿ‘ฏ Two Pointers โฐ: O(NlogN) ๐Ÿช: O(1)

var twoSum = function(nums, target) {
var twoSum = function(nums, target) {
let checkSum = new Map();
for(let i=0; i=0; i--){
result[i] *= right;
right *= nums[i];
}
return result;
};

## [Maximum Subarray](https://leetcode.com/problems/maximum-subarray/) #53 ๐Ÿ“ˆ
โ“: Given an integer array nums, find the contiguous subarray (containing at least one number) which has the largest sum & return its sum.
๐Ÿฃ: Input: nums = [-2,1,-3,4,-1,2,1,-5,4], Output: 6, Explain: [4,-1,2,1] has the largest sum = 6.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N^2) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Pattern Kadane's Algorithm โฐ: O(N) ๐Ÿช: O(1)

var maxSubArray = function(nums) {
let max = nums[0];
let curr = nums[0];
for(let i=1; i nums[right]){
left = mid+1;
} else {
right = mid;
}
}
return nums[left];
};
## [Find Minimum in Rotated Sorted Array](https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/) #153 ๐Ÿ๐Ÿ”š
โ“: Suppose an array of length n sorted in ascending order is rotated between 1 & n times. For example, the array nums = [0,1,2,4,5,6,7] might become:
[4,5,6,7,0,1,2] if it was rotated 4 times.
[0,1,2,4,5,6,7] if it was rotated 7 times.
Notice that rotating an array [a[0], a[1], a[2], ..., a[n-1]] 1 time results in the array [a[n-1], a[0], a[1], a[2], ..., a[n-2]].
Given the sorted rotated array nums of unique elements, return the minimum element of this array.
๐Ÿฃ: Input: nums = [3,4,5,1,2], Output: 1

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿ๐Ÿ”š Mod Binary Search โฐ: O(logN) ๐Ÿช: O(1)

var findMin = function(nums) {
let left = 0;
let right = nums.length-1;
while(left < right){
let mid = Math.floor((left+right)/2);
if(nums[mid] > nums[right]){
left = mid+1;
} else {
right = mid;
}
}
return nums[left];
};
## [Search in Rotated Sorted Array](https://leetcode.com/problems/search-in-rotated-sorted-array/) #33 ๐Ÿ๐Ÿ”š
โ“: You are given an integer array nums sorted in ascending order, & an integer target.
Suppose that nums is rotated at some pivot unknown to you beforeh& (i.e., [0,1,2,4,5,6,7] might become [4,5,6,7,0,1,2]).
If target is found in the array return its index, otherwise, return -1.
๐Ÿฃ: Input: nums = [4,5,6,7,0,1,2], target = 0, Output: 4

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿ๐Ÿ”š Mod Binary Search โฐ: O(logn) ๐Ÿช: O(1)

var search = function(nums, target) {
let left = 0;
let right = nums.length-1;
while(left <= right){
let mid = Math.floor((left+right)/2);
if(nums[mid] === target){
return mid;
} else if(nums[mid] >= nums[left]){
if(target >= nums[left] && target < nums[mid]){
right = mid-1;
} else {
left = mid+1;
}
} else {
if(target > nums[mid] && target <= nums[right]){
left = mid+1;
} else {
right = mid-1;
}
}
}
return -1;
};
## [3Sum](https://leetcode.com/problems/3sum/) #15 ๐Ÿ‘ฏ
โ“: Given an integer array nums, return all the triplets [nums[i], nums[j], nums[k]] such that i != j, i != k, & j != k, & nums[i] + nums[j] + nums[k] == 0.
Notice that the solution set must not contain duplicate triplets.
๐Ÿฃ: Input: nums = [-1,0,1,2,-1,-4], Output: [[-1,-1,2],[-1,0,1]]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N^3) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿ‘ฏ Two Pointers โฐ: O(N^2) ๐Ÿช: O(N)

var threeSum = function(nums) {
let result = [];
nums.sort((a,b) => a-b);
for(let i=0; i 0 && nums[i] === nums[i-1]) continue;
let left = i+1;
let right = nums.length-1;
while(left < right){
let sum = nums[i] + nums[left] + nums[right];
if(sum === 0){
result.push([nums[i], nums[left], nums[right]]);
while(left < right && nums[left] === nums[left+1]) left++;
while(left < right && nums[right] === nums[right-1]) right--;
left++;
right--;
} else if(sum < 0){
left++;
} else {
right--;
}
}
}
return result;
};
## [Container With Most Water](https://leetcode.com/problems/container-with-most-water/) #11 ๐Ÿ‘ฏ
โ“: Given n non-negative integers a1, a2, ..., an , where each represents a poat coordinate (i, ai) n vertical lines are drawn such that the two endpoints of the line i is at (i, ai) & (i, 0) Find two lines, which, together with the x-axis forms a container, such that the container contains the most water
Notice that you may not slant the container.
๐Ÿฃ: Input: height = [1,8,6,2,5,4,8,3,7], Output: 49

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^2) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿ‘ฏ Two Pointers โฐ: O(n) ๐Ÿช: O(1)

var maxArea = function(height) {
let left = 0;
let right = height.length-1;
let max = 0;
while(left < right){
let area = Math.min(height[left], height[right]) * (right-left);
max = Math.max(max, area);
if(height[left] < height[right]){
left++;
} else {
right--;
}
}
return max;
};

---

## Binary

## [Sum of Two Integers](https://leetcode.com/problems/sum-of-two-integers/) ๐Ÿงฉ
โ“: Given two integers a & b, return sum of the two integers without using the operators + & -.
๐Ÿฃ: 1๏ธโƒฃ Input: a = 1, b = 2. Output: 3 2๏ธโƒฃ Input: a = 2, b = 3 Output: 5.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿงฉ Bit Manipulation โฐ: O(1) ๐Ÿช: O(1)

var getSum = function(a, b) {
let carry; // store carry
while(a!==0){
carry = a & b;
b = a ^ b;
a = carry << 1;
}
return b
};
## [Divide Two Integers](https://leetcode.com/problems/divide-two-integers/) #29 ๐Ÿงฉ
โ“: Given two integers dividend & divisor, divide two integers without using multiplication, division, & mod operator.
Return the quotient after dividing dividend by divisor.
The integer division should truncate toward zero, which means losing its fractional part. For example, truncate(8.345) = 8 & truncate(-2.7335) = -2.
Note: Assume we are dealing with an environment that could only store integers within the 32-bit signed integer range: [โˆ’231, 231 โˆ’ 1]. For this problem, assume that your function returns 231 โˆ’ 1 when the division result overflows.
๐Ÿฃ: Input: dividend = 10, divisor = 3, Output: 3

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿงฉ Bit Manipulation โฐ: O(logn) ๐Ÿช: O(logn)

var divide = function(dividend, divisor) {
if (dividend === 0 || divisor === 0) return 0
let isNegative = false;
let quotient = 0;
if ((divisor < 0 || dividend < 0) && !(divisor < 0 && dividend < 0)) isNegative = true;
dividend = Math.abs(dividend)
divisor = Math.abs(divisor)
while (dividend >= divisor) {
let carry = 1, tempDividend= dividend, tempDivisor = divisor
while (tempDivisor <= (tempDividend>> 1)){
carry <<= 1
tempDividend>>= 1
tempDivisor <<= 1
}
quotient += carry
dividend -= tempDivisor
}
if (isNegative) return -quotient
if (quotient >= 2**31) {
return 2**31 - 1
}
return quotient
};
## [Number of 1 Bits](https://leetcode.com/problems/number-of-1-bits/) #191 ๐Ÿงฉ
โ“: Write a function that takes an unsigned integer & returns the number of '1' bits it has (aka Hamming weight).
๐Ÿฃ: 1๏ธโƒฃ Input: n = 00000000000000000000000000001011 Output: 3 . N as a total of three '1' bits.2๏ธโƒฃ Input: n = 00000000000000000000000010000000 Output: 1 3๏ธโƒฃ Input: n = 11111111111111111111111111111101 Output: 31

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿงฉ Bit Manipulation โฐ: O(1) ๐Ÿช: O(1)

var hammingWeight = function(n) {
let count = 0;
while(n!=0){
n = n&(n-1); //mask<<1
count++;
}
return count
};

## [Counting Bits](https://leetcode.com/problems/counting-bits/) #338 ๐Ÿงฉ
โ“: Given an integer n, return an array ans of length n + 1 such that for each i (0 <= i <= n), ans[i] is the number of 1's in the binary representation of i.
๐Ÿฃ: 1๏ธโƒฃ Input: n = 2 Output: [0,1,1] Explain: 0 --> 0 1 --> 1 2 --> 10 2๏ธโƒฃ Input: n = 5 Output: [0,1,1,2,1,2]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿงฉ Bit Manipulation โฐ: O(N) ๐Ÿช: O(1)

var countBits = function(n) {
let result = [0];
for(let i = 1; i <= n; i++){
result.push(result[i>>1] + (i&1));
}
return result;
};

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(N)
๐Ÿ‡ Solution: ๐Ÿงฉ Bit Manipulation โฐ: O(n) ๐Ÿช: O(n)

const countBits = (n) => {
const res = new Array(n);
res[0] = 0;

for (let i = 1; i <= n; i++) {
if (i % 2 === 0) res[i] = res[i / 2];
else res[i] = res[i - 1] + 1;
}

return res;
};
## [Missing Number](https://leetcode.com/problems/missing-number/) #268 ๐Ÿงฉ
โ“: Given an [] containing n distinct numbers in the range [0, n], return the only num in the range tht missing from the []
๐Ÿฃ: 1๏ธโƒฃ Input: nums = [3,0,1] Output: 2 Explain: n = 3 since there are 3 num, so all n are in range [0,3]. 2 is the missing num in the range it does not appear in nums. 2๏ธโƒฃ Input: nums = [0,1] Output: 2 3๏ธโƒฃ Input: nums = [9,6,4,2,3,5,7,0,1] Output: 8

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(N)
๐Ÿ‡ Solution: ๐Ÿงฉ Bit Manipulation โฐ: O(n) ๐Ÿช: O(n)

var missingNumber = function (nums) {
let i = 0;
let temp = 0;
while (i < nums.length) {
if (nums[i] != i && nums.length > nums[i]) {
temp = nums[nums[i]];
nums[nums[i]] = nums[i];
nums[i] = temp;
} else {
i++;
}
}

for (let i = 0; i < nums.length; i++) {
if (i != nums[i]) return i;
}

return nums.length;
};

## [Reverse Bits](https://leetcode.com/problems/reverse-bits/) #190 ๐Ÿงฉ
โ“: Reverse bits of a given 32 bits unsigned integer.
๐Ÿฃ: 1๏ธโƒฃ Input: n = 00000010100101000001111010011100 Output: 964176192 (00111001011110000010100101000000)
Explain: The input binary string 00000010100101000001111010011100 represents the unsigned integer 43261596, so return 964176192 which its binary representation is 00111001011110000010100101000000. 2๏ธโƒฃ Input: n = 11111111111111111111111111111101
Output: 3221225471 (10111111111111111111111111111111)

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(N) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿงฉ Bit Manipulation โฐ: O(1) ๐Ÿช: O(1)

var reverseBits = function (n) {
var len = 32;
var arr = new Array();
while (len > 0) {
var t = n & 1;
n = n >> 1;
arr.push(t);
len--;
}
var res = arr.join("");
return parseInt(res, 2);
};

## ๐Ÿ“ˆ Dynamic Programming

## [Climbing Stairs](https://leetcode.com/problems/climbing-stairs/) #70 ๐Ÿ“ˆ
โ“: You are climbing a staircase. It takes n steps to reach the top. Each time you can either climb 1 or 2 steps. In how many distinct ways can you climb to the top?
๐Ÿฃ: 1๏ธโƒฃ Input: n = 2 Output: 2. Explain: There are two ways to climb to the top. 1. 1 step + 1 step 2. 2 steps
2๏ธโƒฃ Input: n = 3 Output: 3. Explain: There are three ways to climb to the top. 1. 1 step + 1 step + 1 step 2. 1 step + 2 steps 3. 2 steps + 1 step

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n) ๐Ÿช: O(n)

var climbStairs = function (n) {
if (n == 1) return 1;
if (n == 2) return 2;
let dp = new Array(n + 1); // ways to climb array
dp[1] = 1;
dp[2] = 2;
for (let i = 3; i <= n; i++) { //Either climb 1 stair & then climb the rest i-1 stairs X ways.
dp[i] = dp[i - 1] + dp[i - 2]; //- Or climb 2 stairs at once & then climb the rest i-2 stairs Y ways.
} //Total: X + Y ways
return dp[n];
};
## [Coin Change](https://leetcode.com/problems/coin-change/) #322 ๐Ÿ“ˆ
โ“: You are given an integer array coins representing coins of different denominations & an integer amount representing a total amount of money. Return the fewest number of coins that you need to make up that amount. If that amount of money cannot be made up by any combination of the coins, return -1.
๐Ÿฃ: 1๏ธโƒฃ Input: coins = [1,2,5], amount = 11 Output: 3 Explain: 11 = 5 + 5 + 1
2๏ธโƒฃ Input: coins = [2], amount = 3 Output: -1
3๏ธโƒฃ Input: coins = [1], amount = 0 Output: 0

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^amount) ๐Ÿช: O(amount)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n^amount) ๐Ÿช: O(n^amount)

var coinChange = function (coins, amount) {
let dp = new Array(amount + 1).fill(amount + 1);
dp[0] = 0;
for (let i = 1; i <= amount; i++) {
for (let j = 0; j < coins.length; j++) {
if (coins[j] <= i) {
dp[i] = Math.min(dp[i], dp[i - coins[j]] + 1);
}
}
}
return dp[amount] > amount ? -1 : dp[amount];
};
## [Longest Increasing Subsequence](https://leetcode.com/problems/longest-increasing-subsequence/) #300 ๐Ÿ“ˆ
โ“: Given an integer array nums, return the length of the longest strictly increasing subsequence.
๐Ÿฃ: 1๏ธโƒฃ Input: nums = [10,9,2,5,3,7,101,18] Output: 4 Explain: The longest increasing subsequence is [2,3,7,101], therefore the length is 4. 2๏ธโƒฃ Input: nums = [0,1,0,3,2,3] Output: 4 3๏ธโƒฃ Input: nums = [7,7,7,7,7,7,7] Output: 1

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n^2) ๐Ÿช: O(n^2)

var lengthOfLIS = function (nums) {
let dp = new Array(nums.length).fill(1);
let max = 1;
for (let i = 1; i < nums.length; i++) {
for (let j = 0; j < i; j++) {
if (nums[i] > nums[j]) {
dp[i] = Math.max(dp[i], dp[j] + 1);
max = Math.max(max, dp[i]);
}
}
}
return max;
};

## [Longest Common Subsequence](https://leetcode.com/problems/longest-common-subsequence/) #1143 ๐Ÿ“ˆ
โ“: Given two strings text1 & text2, return the length of their longest common subsequence. If there is no common subsequence, return 0. A subsequence of a string is a new string generated from the original string with some characters(can be none) deleted without changing the relative order of the remaining characters. (eg, "ace" is a subsequence of "abcde" while "aec" is not). A common subsequence of two strings is a subsequence that is common to both strings.
๐Ÿฃ: 1๏ธโƒฃ Input: text1 = "abcde", text2 = "ace" Output: 3 Explain: The longest common subsequence is "ace" & its length is 3. 2๏ธโƒฃ Input: text1 = "abc", text2 = "abc" Output: 3 3๏ธโƒฃ Input: text1 = "abc", text2 = "def" Output: 0

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(m*n) ๐Ÿช: O(m*n)

var longestCommonSubsequence = function (text1, text2) {
let dp = new Array(text1.length + 1)
.fill(0)
.map(() => new Array(text2.length + 1).fill(0));
for (let i = 1; i <= text1.length; i++) {
for (let j = 1; j <= text2.length; j++) {
if (text1[i - 1] == text2[j - 1]) {
dp[i][j] = dp[i - 1][j - 1] + 1;
} else {
dp[i][j] = Math.max(dp[i - 1][j], dp[i][j - 1]);
}
}
}
return dp[text1.length][text2.length];
};
## [Word Break Problem](https://leetcode.com/problems/word-break/)๐Ÿ“ˆ
โ“: Given a string s & a dictionary of strings wordDict, return true if s can be segmented into a space-separated sequence of one or more dictionary words. Note that the same word in the dictionary may be reused multiple times in the segmentation.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "leetcode", wordDict = ["leet","code"] Output: true Explain: Return true because "leetcode" can be segmented as "leet code". 2๏ธโƒฃ Input: s = "applepenapple", wordDict = ["apple","pen"] Output: true Explain: Return true because "applepenapple" can be segmented as "apple pen apple". Note that you are allowed to reuse a dictionary word. 3๏ธโƒฃ Input: s = "cats&og", wordDict = ["cats","dog","s&","&","cat"] Output: false

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n^2) ๐Ÿช: O(n^2)

var wordBreak = function (s, wordDict) {
let dp = new Array(s.length + 1).fill(false);
dp[0] = true;
for (let i = 1; i <= s.length; i++) {
for (let j = 0; j < i; j++) {
if (dp[j] && wordDict.includes(s.substring(j, i))) {
dp[i] = true;
break;
}
}
}
return dp[s.length];
};
## [Combination Sum](https://leetcode.com/problems/combination-sum-iv/) #377 ๐Ÿ“ˆ
โ“: Given an integer array with all positive numbers & no duplicates, find the number of possible combinations that add up to a positive integer target.
๐Ÿฃ: Input: nums = [1, 2, 3] target = 4 Output: 7 Explain: The possible combination ways are: (1, 1, 1, 1) (1, 1, 2) (1, 2, 1) (1, 3) (2, 1, 1) (2, 2) (3, 1) Note that different sequences are counted as different combinations. Therefore the output is 7.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n*target) ๐Ÿช: O(n*target)

var combinationSum4 = function (nums, target) {
let dp = new Array(target + 1).fill(0);
dp[0] = 1;
for (let i = 1; i <= target; i++) {
for (let j = 0; j < nums.length; j++) {
if (nums[j] <= i) {
dp[i] += dp[i - nums[j]];
}
}
}
return dp[target];
};
## [House Robber](https://leetcode.com/problems/house-robber/) #198
โ“: You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed, the only constrastopping you from robbing each of them is that adjacent houses have security system connected & it will automatically contact the police if two adjacent houses were broken into on the same night. Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.
๐Ÿฃ: 1๏ธโƒฃ Input: nums = [1,2,3,1] Output: 4 Explain: Rob house 1 (money = 1) & then rob house 3 (money = 3). Total amount you can rob = 1 + 3 = 4. 2๏ธโƒฃ Input: nums = [2,7,9,3,1] Output: 12 Explain: Rob house 1 (money = 2), rob house 3 (money = 9) & rob house 5 (money = 1). Total amount you can rob = 2 + 9 + 1 = 12.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n) ๐Ÿช: O(n)

var rob = function (nums) {
let dp = new Array(nums.length + 1).fill(0);
dp[0] = 0;
dp[1] = nums[0];
for (let i = 2; i <= nums.length; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i - 1]);
}
return dp[nums.length];
};
## [House Robber II](https://leetcode.com/problems/house-robber-ii/) #213

โ“: You are a professional robber planning to rob houses along a street. Each house has a certain amount of money stashed. All houses at this place are arranged in a circle. That means the first house is the neighbor of the last one. Meanwhile, adjacent houses have security system connected & it will automatically contact the police if two adjacent houses were broken into on the same night. Given an integer array nums representing the amount of money of each house, return the maximum amount of money you can rob tonight without alerting the police.
๐Ÿฃ: 1๏ธโƒฃ Input: nums = [2,3,2] Output: 3 Explain: You cannot rob house 1 (money = 2) & then rob house 3 (money = 2), because they are adjacent houses. 2๏ธโƒฃ Input: nums = [1,2,3,1] Output: 4 Explain: Rob house 1 (money = 1) & then rob house 3 (money = 3). Total amount you can rob = 1 + 3 = 4. 3๏ธโƒฃ Input: nums = [0] Output: 0

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n) ๐Ÿช: O(n)

var rob = function (nums) {
if (nums.length == 1) return nums[0];
return Math.max(
robRange(nums, 0, nums.length - 2),
robRange(nums, 1, nums.length - 1)
);
};
var robRange = function (nums, start, end) {
let dp = new Array(nums.length + 1).fill(0);
dp[start] = nums[start];
dp[start + 1] = Math.max(nums[start], nums[start + 1]);
for (let i = start + 2; i <= end; i++) {
dp[i] = Math.max(dp[i - 1], dp[i - 2] + nums[i]);
}
return dp[end];
};
## [Decode Ways](https://leetcode.com/problems/decode-ways/) #91 ๐Ÿ“ˆ
โ“: A message containing letters from A-Z is being encoded to numbers using the following mapping: 'A' -> 1 'B' -> 2 ... 'Z' -> 26 Given a non-empty string s containing only digits, determine the total number of ways to decode it. The answer is guaranteed to fit in a 32-bit integer.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "12" Output: 2 Explain: It could be decoded as "AB" (1 2) or "L" (12). 2๏ธโƒฃ Input: s = "226" Output: 3 Explain: It could be decoded as "BZ" (2 26), "VF" (22 6), or "BBF" (2 2 6). 3๏ธโƒฃ Input: s = "0" Output: 0 Explain: There is no character that is mapped to a number starting with 0. The only valid mappings with 0 are 'J' -> "10" & 'T' -> "20", neither of which start with 0. Hence, there are no valid ways to decode this since all digits need to be mapped. #4 Input: s = "1" Output: 1

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n) ๐Ÿช: O(n)

var numDecodings = function (s) {
if (s[0] == "0") return 0;
let dp = new Array(s.length + 1).fill(0);
dp[0] = 1;
dp[1] = 1;
for (let i = 2; i <= s.length; i++) {
let first = parseInt(s.substring(i - 1, i));
let second = parseInt(s.substring(i - 2, i));
if (first >= 1 && first <= 9) {
dp[i] += dp[i - 1];
}
if (second >= 10 && second <= 26) {
dp[i] += dp[i - 2];
}
}
return dp[s.length];
};
## [Unique Paths](https://leetcode.com/problems/unique-paths/) #62 ๐Ÿ“ˆ

โ“: A robot is located at the top-left corner of a m x n grid (marked 'Start' in the diagram below). The robot can only move either down or right at any poin time. The robot is trying to reach the bottom-right corner of the grid (marked 'Finish' in the diagram below). How many possible unique paths are there?
๐Ÿฃ: 1๏ธโƒฃ Input: m = 3, n = 7 Output: 28 2๏ธโƒฃ Input: m = 3, n = 2 Output: 3 Explain: From the top-left corner, there are a total of 3 ways to reach the bottom-right corner: 1. Right -> Down -> Down 2. Down -> Down -> Right 3. Down -> Right -> Down 3๏ธโƒฃ Input: m = 7, n = 3 Output: 28 #4 Input: m = 3, n = 3 Output: 6

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Memoization โฐ: O(n) ๐Ÿช: O(n)

var uniquePaths = function (m, n) {
let dp = new Array(m).fill(0).map(() => new Array(n).fill(0));
for (let i = 0; i < m; i++) {
dp[i][0] = 1;
}
for (let j = 0; j < n; j++) {
dp[0][j] = 1;
}
for (let i = 1; i < m; i++) {
for (let j = 1; j < n; j++) {
dp[i][j] = dp[i - 1][j] + dp[i][j - 1];
}
}
return dp[m - 1][n - 1];
};
## [Jump Game](https://leetcode.com/problems/jump-game/) #55 ๐Ÿ“ˆ

โ“: Given an array of non-negative integers nums, you are initially positioned at the first index of the array. Each element in the array represents your maximum jump length at that position. Determine if you are able to reach the last index.
๐Ÿฃ: 1๏ธโƒฃ Input: nums = [2,3,1,1,4] Output: true Explain: Jump 1 step from index 0 to 1, then 3 steps to the last index. 2๏ธโƒฃ Input: nums = [3,2,1,0,4] Output: false Explain: You will always arrive at index 3 no matter what. Its maximum jump length is 0, which makes it impossible to reach the last index.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(2^n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming Tabulation โฐ: O(n) ๐Ÿช: O(n)

var canJump = function (nums) {
let dp = new Array(nums.length).fill(false);
dp[0] = true;
for (let i = 1; i < nums.length; i++) {
for (let j = 0; j < i; j++) {
if (dp[j] && j + nums[j] >= i) {
dp[i] = true;
break;
}
}
}
return dp[nums.length - 1];
};

---
## Graph

## [Clone Graph](https://leetcode.com/problems/clone-graph/) #133 ๐ŸŒณ
โ“: Given a reference of a node in a connected undirected graph. Return a deep copy (clone) of the graph. Each node in the graph contains a val (int) & a list (List[Node]) of its neighbors.
๐Ÿฃ: 1๏ธโƒฃ Input: adjList = [[2,4],[1,3],[2,4],[1,3]] Output: [[2,4],[1,3],[2,4],[1,3]] Explain: There are 4 nodes in the graph. 2๏ธโƒฃ Input: adjList = [[]] Output: [[]] 3๏ธโƒฃ Input: adjList = [] Output: [] #4 Input: adjList = [[2],[1]] Output: [[2],[1]]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐ŸŒณ BFS โฐ: O(n) ๐Ÿช: O(n)

var cloneGraph = function (node) {
if (!node) return node;
let map = new Map();
let clone = new Node(node.val, []);
map.set(node, clone);
let queue = [node];
while (queue.length) {
let n = queue.shift();
for (let neighbor of n.neighbors) {
if (!map.has(neighbor)) {
map.set(neighbor, new Node(neighbor.val, []));
queue.push(neighbor);
}
map.get(n).neighbors.push(map.get(neighbor));
}
}
return clone;
};

## [Course Schedule](https://leetcode.com/problems/course-schedule/) #207 ๐Ÿ“…
โ“: There are a total of numCourses courses you have to take, labeled from 0 to numCourses - 1. You are given an array prerequisites where prerequisites[i] = [ai, bi] indicates that you must take course bi first if you want to take course ai. For example, the pair [0, 1], indicates that to take course 0 you have to first take course 1. Return true if you can finish all courses. Otherwise, return false.
๐Ÿฃ: 1๏ธโƒฃ Input: numCourses = 2, prerequisites = [[1,0]] Output: true Explain: There are a total of 2 courses to take. To take course 1 you should have finished course 0. So it is possible. 2๏ธโƒฃ Input: numCourses = 2, prerequisites = [[1,0],[0,1]] Output: false Explain: There are a total of 2 courses to take. To take course 1 you should have finished course 0, & to take course 0 you should also have finished course 1. So it is impossible.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿ“… Topological Sort โฐ: O(V+E) ๐Ÿช: O(V+E)

var canFinish = function (numCourses, prerequisites) {
let graph = new Map();
let indegree = new Array(numCourses).fill(0);
for (let [course, pre] of prerequisites) {
if (!graph.has(pre)) graph.set(pre, []);
graph.get(pre).push(course);
indegree[course]++;
}
let queue = [];
for (let i = 0; i < indegree.length; i++) {
if (indegree[i] == 0) queue.push(i);
}
let count = 0;
while (queue.length) {
let course = queue.shift();
count++;
if (graph.has(course)) {
for (let next of graph.get(course)) {
indegree[next]--;
if (indegree[next] == 0) queue.push(next);
}
}
}
return count == numCourses;
};

## [Pacific Atlantic Water Flow](https://leetcode.com/problems/pacific-atlantic-water-flow/) #417 ๐ŸŒณ
โ“: Given an m x n matrix of non-negative integers representing the height of each unit cell in a continent, the "Pacific ocean" touches the left & top edges of the matrix & the "Atlantic ocean" touches the right & bottom edges. Water can only flow in four directions (up, down, left, or right) from a cell to another one with height equal or lower. Find the list of grid coordinates where water can flow to both the Pacific & Atlantic ocean.
๐Ÿฃ: 1๏ธโƒฃ Input: heights = [[1,2,2,3,5],[3,2,3,4,4],[2,4,5,3,1],[6,7,1,4,5],[5,1,1,2,4]] Output: [[0,4],[1,3],[1,4],[2,2],[3,0],[3,1],[4,0]] Explain: Pacific ~ ~ ~ ~ ~ 1 2 2 3 (5) ~ 3 2 3 (4) (4) ~ 2 4 (5) 3 1 ~ (6) (7) 1 4 5 ~ (5) 1 1 2 4 ~ ~ ~ ~ ~ Atlantic 2๏ธโƒฃ Input: heights = [[2,1],[1,2]] Output: [[0,0],[0,1],[1,0],[1,1]]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐ŸŒณ BFS โฐ: O(n) ๐Ÿช: O(n)

var pacificAtlantic = function (heights) {
let m = heights.length;
let n = heights[0].length;
let pacific = new Array(m).fill(0).map(() => new Array(n).fill(false));
let atlantic = new Array(m).fill(0).map(() => new Array(n).fill(false));
let queue = [];
for (let i = 0; i < m; i++) {
queue.push([i, 0]);
pacific[i][0] = true;
}
for (let i = 0; i < n; i++) {
queue.push([0, i]);
pacific[0][i] = true;
}
๐ŸŒณ BFS(heights, pacific, queue);
queue = [];
for (let i = 0; i < m; i++) {
queue.push([i, n - 1]);
atlantic[i][n - 1] = true;
}
for (let i = 0; i < n; i++) {
queue.push([m - 1, i]);
atlantic[m - 1][i] = true;
}
๐ŸŒณ BFS(heights, atlantic, queue);
let res = [];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (pacific[i][j] && atlantic[i][j]) res.push([i, j]);
}
}
return res;
};

function ๐ŸŒณ BFS(heights, ocean, queue) {
let dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]];
while (queue.length) {
let [i, j] = queue.shift();
for (let dir of dirs) {
let x = i + dir[0];
let y = j + dir[1];
if (
x >= 0 &&
x < heights.length &&
y >= 0 &&
y < heights[0].length &&
!ocean[x][y]
) {
if (heights[x][y] >= heights[i][j]) {
ocean[x][y] = true;
queue.push([x, y]);
}
}
}
}
}


## [Number of Islands](https://leetcode.com/problems/number-of-islands/) #200 ๐ŸŒณ
Pattern Used: ๐ŸŒณ BFS Pattern ๐ŸŒฒ DFS Pattern Union Find Pattern
โ“: Given an m x n 2d grid map of '1's (l&) & '0's (water), return the number of islands. An isl& is surrounded by water & is formed by connecting adjacent l&s horizontally or vertically. You may assume all four edges of the grid are all surrounded by water.
๐Ÿฃ: 1๏ธโƒฃ Input: grid = [ ["1","1","1","1","0"], ["1","1","0","1","0"], ["1","1","0","0","0"], ["0","0","0","0","0"] ] Output: 1 2๏ธโƒฃ Input: grid = [ ["1","1","0","0","0"], ["1","1","0","0","0"], ["0","0","1","0","0"], ["0","0","0","1","1"] ] Output: 3

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐ŸŒณ BFS โฐ: O(mn) ๐Ÿช: O(mn)

var numIslands = function (grid) {
let m = grid.length;
let n = grid[0].length;
let count = 0;
let dirs = [[0, 1], [0, -1], [1, 0], [-1, 0]];
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (grid[i][j] == "1") {
count++;
grid[i][j] = "0";
let queue = [[i, j]];
while (queue.length) {
let [x, y] = queue.shift();
for (let dir of dirs) {
let a = x + dir[0];
let b = y + dir[1];
if (
a >= 0 &&
a < m &&
b >= 0 &&
b < n &&
grid[a][b] == "1"
) {
grid[a][b] = "0";
queue.push([a, b]);
}
}
}
}
}
}
return count;
};
## [Longest Consecutive Sequence](https://leetcode.com/problems/longest-consecutive-sequence/) #128 โ™พ
โ“: Given an unsorted array of integers nums, return the length of the longest consecutive elements sequence. You must write an algorithm that runs in O(n) time.
๐Ÿฃ: 1๏ธโƒฃ Input: nums = [100,4,200,1,3,2] Output: 4 Explain: The longest consecutive elements sequence is [1, 2, 3, 4]. Therefore its length is 4. 2๏ธโƒฃ Input: nums = [0,3,7,2,5,8,4,6,0,1] Output: 9

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: โ™พ Union Find โฐ: O(n) ๐Ÿช: O(n)

var longestConsecutive = function (nums) {
let set = new Set(nums);
let max = 0;
for (let num of set) {
if (!set.has(num - 1)) {
let curr = num;
let count = 1;
while (set.has(curr + 1)) {
curr++;
count++;
}
max = Math.max(max, count);
}
}
return max;
};

## Interval

## [Insert Interval](https://leetcode.com/problems/insert-interval/) #57 ๐Ÿš—๐Ÿš™
โ“: Given a set of non-overlapping intervals, insert a new interval into the intervals (merge if necessary). You may assume that the intervals were initially sorted according to their start times.
๐Ÿฃ: 1๏ธโƒฃ Input: intervals = [[1,3],[6,9]], newInterval = [2,5] Output: [[1,5],[6,9]] 2๏ธโƒฃ Input: intervals = [[1,2],[3,5],[6,7],[8,10],[12,16]], newInterval = [4,8] Output: [[1,2],[3,10],[12,16]] Explain: Because the new interval [4,8] overlaps with [3,5],[6,7],[8,10].

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿš—๐Ÿš™ Merge Intervals โฐ: O(n) ๐Ÿช: O(n)

var insert = function (intervals, newInterval) {
let res = [];
let i = 0;
while (i < intervals.length && intervals[i][1] < newInterval[0]) {
res.push(intervals[i]);
i++;
}
while (i < intervals.length && intervals[i][0] <= newInterval[1]) {
newInterval[0] = Math.min(newInterval[0], intervals[i][0]);
newInterval[1] = Math.max(newInterval[1], intervals[i][1]);
i++;
}
res.push(newInterval);
while (i < intervals.length) {
res.push(intervals[i]);
i++;
}
return res;
};
## [Merge Intervals](https://leetcode.com/problems/merge-intervals/) #56 ๐Ÿš—๐Ÿš™ ๐Ÿ’ฐ
โ“: Given an array of intervals where intervals[i] = [starti, endi], merge all overlapping intervals, & return an array of the non-overlapping intervals that cover all the intervals in the input.
๐Ÿฃ: 1๏ธโƒฃ Input: intervals = [[1,3],[2,6],[8,10],[15,18]] Output: [[1,6],[8,10],[15,18]] Explain: Since intervals [1,3] & [2,6] overlaps, merge them into [1,6]. 2๏ธโƒฃ Input: intervals = [[1,4],[4,5]] Output: [[1,5]] Explain: Intervals [1,4] & [4,5] are considered overlapping.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿš—๐Ÿš™ Merge Intervals โฐ: O(n) ๐Ÿช: O(n)

var merge = function (intervals) {
if (intervals.length <= 1) return intervals;
intervals.sort((a, b) => a[0] - b[0]);
let res = [intervals[0]];
for (let i = 1; i < intervals.length; i++) {
let curr = intervals[i];
let prev = res[res.length - 1];
if (curr[0] <= prev[1]) {
prev[1] = Math.max(prev[1], curr[1]);
} else {
res.push(curr);
}
}
return res;
};

## [Non-overlapping Intervals](https://leetcode.com/problems/non-overlapping-intervals/) #435 ๐Ÿš—๐Ÿš™
โ“: Given an array of intervals intervals where intervals[i] = [starti, endi], return the minimum number of intervals you need to remove to make the rest of the intervals non-overlapping.
๐Ÿฃ: 1๏ธโƒฃ Input: intervals = [[1,2],[2,3],[3,4],[1,3]] Output: 1 Explain: [1,3] can be removed & the rest of the intervals are non-overlapping. 2๏ธโƒฃ Input: intervals = [[1,2],[1,2],[1,2]] Output: 2 Explain: You need to remove two [1,2] to make the rest of the intervals non-overlapping. 3๏ธโƒฃ Input: intervals = [[1,2],[2,3]] Output: 0 Explain: You don't need to remove any of the intervals since they're already non-overlapping.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿš—๐Ÿš™ Merge Intervals โฐ: O(nlogn) ๐Ÿช: O(1)

var eraseOverlapIntervals = function (intervals) {
if (intervals.length <= 1) return 0;
intervals.sort((a, b) => a[1] - b[1]);
let count = 0;
let prev = intervals[0];
for (let i = 1; i < intervals.length; i++) {
let curr = intervals[i];
if (curr[0] < prev[1]) {
count++;
} else {
prev = curr;
}
}
return count;
};
---

## Linked List

## [Reverse a Linked List](https://leetcode.com/problems/reverse-linked-list/) #206 ๐Ÿฐ&๐Ÿข
โ“: Given the head of a singly linked list, reverse the list, & return the reversed list.
๐Ÿฃ: 1๏ธโƒฃ Input: head = [1,2,3,4,5] Output: [5,4,3,2,1] 2๏ธโƒฃ Input: head = [1,2] Output: [2,1] 3๏ธโƒฃ Input: head = [] Output: []

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: ๐Ÿ”จ Brute Force โฐ:
๐Ÿ‡ Solution: ๐Ÿฐ&๐Ÿข Fast & Slow Pointers โฐ: O(n) ๐Ÿช: O(1)

var reverseList = function (head) {
let prev = null;
let curr = head;
while (curr) {
let next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
return prev;
};
which algorithm from ./algorithms.md is used in this solution?
the
## [Detect Cycle in a Linked List](https://leetcode.com/problems/linked-list-cycle/) #141 ๐Ÿฐ&๐Ÿข
โ“: Given head, the head of a linked list, determine if the linked list has a cycle in it. There is a cycle in a linked list if there is some node in the list that can be reached again by continuously following the next pointer. Internally, pos is used to denote the index of the node that tail's next pointer is connected to. Note that pos is not passed as a parameter. Return true if there is a cycle in the linked list. Otherwise, return false.
๐Ÿฃ: 1๏ธโƒฃ Input: head = [3,2,0,-4], pos = 1 Output: true Explain: There is a cycle in the linked list, where the tail connects to the 1st node (0-indexed). 2๏ธโƒฃ Input: head = [1,2], pos = 0 Output: true Explain: There is a cycle in the linked list, where the tail connects to the 0th node. 3๏ธโƒฃ Input: head = [1], pos = -1 Output: false Explain: There is no cycle in the linked list.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿฐ&๐Ÿข Fast & Slow Pointers โฐ: O(n) ๐Ÿช: O(1)

var hasCycle = function (head) {
let slow = head;
let fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
if (slow === fast) return true;
}
return false;
};
## [Merge Two Sorted Lists](https://leetcode.com/problems/merge-two-sorted-lists/) #21 ๐Ÿฐ&๐Ÿข
โ“: Merge two sorted linked lists & return it as a sorted list. The list should be made by splicing together the nodes of the first two lists.
๐Ÿฃ: 1๏ธโƒฃ Input: l1 = [1,2,4], l2 = [1,3,4] Output: [1,1,2,3,4,4] 2๏ธโƒฃ Input: l1 = [], l2 = [] Output: [] 3๏ธโƒฃ Input: l1 = [], l2 = [0] Output: [0]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿฐ&๐Ÿข Fast & Slow Pointers โฐ: O(n) ๐Ÿช: O(1)

var mergeTwoLists = function (l1, l2) {
let dummy = new ListNode();
let curr = dummy;
while (l1 && l2) {
if (l1.val < l2.val) {
curr.next = l1;
l1 = l1.next;
} else {
curr.next = l2;
l2 = l2.next;
}
curr = curr.next;
}
if (l1) curr.next = l1;
if (l2) curr.next = l2;
return dummy.next;
};
## [Merge K Sorted Lists](https://leetcode.com/problems/merge-k-sorted-lists/) #23

Pattern Used: K MERGE
โ“: You are given an array of k linked-lists lists, each linked-list is sorted in ascending order. Merge all the linked-lists into one sorted linked-list & return it.
๐Ÿฃ: 1๏ธโƒฃ Input: lists = [[1,4,5],[1,3,4],[2,6]] Output: [1,1,2,3,4,4,5,6] 2๏ธโƒฃ Input: lists = [] Output: [] 3๏ธโƒฃ Input: lists = [[]] Output: []

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: Heap โฐ: O(n) ๐Ÿช: O(n)

import ListNode from "DataStructures/LinkedList/ListNode.js";
import MinHeap from "DataStructures/Heaps/MinHeap.js";

const mergeKLists = function (lists) {
if (lists.length === 0) return null;
let dummy = new ListNode();
let curr = dummy;
let minHeap = new MinHeap();
for (let i = 0; i < lists.length; i++) {
if (lists[i]) minHeap.insert(lists[i]);
}
while (minHeap.size() > 0) {
let node = minHeap.remove();
curr.next = node;
curr = curr.next;
if (node.next) minHeap.insert(node.next);
}
return dummy.next;
};
## [Remove Nth Node From End Of List](https://leetcode.com/problems/remove-nth-node-from-end-of-list/) #19 ๐Ÿฐ&๐Ÿข
โ“: Given the head of a linked list, remove the nth node from the end of the list & return its head.
๐Ÿฃ: 1๏ธโƒฃ Input: head = [1,2,3,4,5], n = 2 Output: [1,2,3,5] 2๏ธโƒฃ Input: head = [1], n = 1 Output: [] 3๏ธโƒฃ Input: head = [1,2], n = 1 Output: [1]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿฐ&๐Ÿข Fast & Slow Pointers Fast & Slow Pointers โฐ: O(n) ๐Ÿช: O(1)

var removeNthFromEnd = function (head, n) {
let dummy = new ListNode();
dummy.next = head;
let slow = dummy;
let fast = dummy;
for (let i = 0; i < n; i++) {
fast = fast.next;
}
while (fast.next) {
slow = slow.next;
fast = fast.next;
}
slow.next = slow.next.next;
return dummy.next;
};
## [Reorder List](https://leetcode.com/problems/reorder-list/) #143 ๐Ÿฐ&๐Ÿข
โ“: Given the head of a singly linked list, reorder the list to be: head -> node 2 -> node 3 -> node 4 -> ... -> node n -> null. You may not modify the values in the list's nodes. Only nodes themselves may be changed.
๐Ÿฃ: 1๏ธโƒฃ Input: head = [1,2,3,4] Output: [1,4,2,3] 2๏ธโƒฃ Input: head = [1,2,3,4,5] Output: [1,5,2,4,3]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐Ÿฐ&๐Ÿข Fast & Slow Pointers โฐ: O(n) ๐Ÿช: O(1)

var reorderList = function (head) {
if (!head) return null;
let slow = head;
let fast = head;
while (fast && fast.next) {
slow = slow.next;
fast = fast.next.next;
}
let prev = null;
let curr = slow;
while (curr) {
let next = curr.next;
curr.next = prev;
prev = curr;
curr = next;
}
let first = head;
let second = prev;
while (second.next) {
let temp = first.next;
first.next = second;
first = temp;
temp = second.next;
second.next = first;
second = temp;
}
};
---

## Matrix

## [Set Matrix Zeroes](https://leetcode.com/problems/set-matrix-zeroes/) #73 ๐Ÿ“
โ“: Given an m x n matrix. If an element is 0, set its entire row & column to 0. Do it in-place.
๐Ÿฃ: 1๏ธโƒฃ Input: matrix = [[1,1,1],[1,0,1],[1,1,1]] Output: [[1,0,1],[0,0,0],[1,0,1]] 2๏ธโƒฃ Input: matrix = [[0,1,2,0],[3,4,5,2],[1,3,1,5]] Output: [[0,0,0,0],[0,4,5,0],[0,3,1,0]]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(mn) ๐Ÿช: O(m+n)
๐Ÿ‡ Solution: ๐Ÿ“ Matrix Pattern โฐ: O(mn) ๐Ÿช: O(1)

var setZeroes = function (matrix) {
let rows = new Set();
let cols = new Set();
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[0].length; j++) {
if (matrix[i][j] === 0) {
rows.add(i);
cols.add(j);
}
}
}
for (let i = 0; i < matrix.length; i++) {
for (let j = 0; j < matrix[0].length; j++) {
if (rows.has(i) || cols.has(j)) {
matrix[i][j] = 0;
}
}
}
};

## [Spiral Matrix](https://leetcode.com/problems/spiral-matrix/) #54 ๐Ÿ“
Pattern Used: ๐Ÿ“ Matrix Pattern
โ“: Given an m x n matrix, return all elements of the matrix in spiral order.
๐Ÿฃ: 1๏ธโƒฃ Input: matrix = [[1,2,3],[4,5,6],[7,8,9]] Output: [1,2,3,6,9,8,7,4,5] 2๏ธโƒฃ Input: matrix = [[1,2,3,4],[5,6,7,8],[9,10,11,12]] Output: [1,2,3,4,8,12,11,10,9,5,6,7]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(mn) ๐Ÿช: O(mn)
๐Ÿ‡ Solution: ๐Ÿ“ Matrix Pattern โฐ: O(mn) ๐Ÿช: O(mn)

var spiralOrder = function (matrix) {
let result = [];
let top = 0;
let bottom = matrix.length - 1;
let left = 0;
let right = matrix[0].length - 1;
while (top <= bottom && left <= right) {
for (let i = left; i <= right; i++) {
result.push(matrix[top][i]);
}
top++;
for (let i = top; i <= bottom; i++) {
result.push(matrix[i][right]);
}
right--;
if (top <= bottom) {
for (let i = right; i >= left; i--) {
result.push(matrix[bottom][i]);
}
bottom--;
}
if (left <= right) {
for (let i = bottom; i >= top; i--) {
result.push(matrix[i][left]);
}
left++;
}
}
return result;
};
## [Rotate Image](https://leetcode.com/problems/rotate-image/) #48 ๐Ÿ“
Pattern Used: ๐Ÿ“ Matrix Pattern
โ“: You are given an n x n 2D matrix representing an image, rotate the image by 90 degrees (clockwise).
๐Ÿฃ: 1๏ธโƒฃ Input: matrix = [[1,2,3],[4,5,6],[7,8,9]] Output: [[7,4,1],[8,5,2],[9,6,3]] 2๏ธโƒฃ Input: matrix = [[5,1,9,11],[2,4,8,10],[13,3,6,7],[15,14,12,16]] Output: [[15,13,2,5],[14,3,4,1],[12,6,8,9],[16,7,10,11]]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: ๐Ÿ”จ Brute Force โฐ:
๐Ÿ‡ Solution: MatrixPattern โฐ: O(n) ๐Ÿช: O(1)

var rotate = function (matrix) {
let n = matrix.length;
for (let i = 0; i < n / 2; i++) {
for (let j = i; j < n - i - 1; j++) {
let temp = matrix[i][j];
matrix[i][j] = matrix[n - j - 1][i];
matrix[n - j - 1][i] = matrix[n - i - 1][n - j - 1];
matrix[n - i - 1][n - j - 1] = matrix[j][n - i - 1];
matrix[j][n - i - 1] = temp;
}
}
};
## [Word Search](https://leetcode.com/problems/word-search/) #79 ๐Ÿ“
Pattern Used: Backtracking ๐Ÿ“ Matrix Pattern
โ“: Given an m x n grid of characters board & a string word, return true if word exists in the grid.
๐Ÿฃ: 1๏ธโƒฃ Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCCED" Output: true 2๏ธโƒฃ Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "SEE" Output: true 3๏ธโƒฃ Input: board = [["A","B","C","E"],["S","F","C","S"],["A","D","E","E"]], word = "ABCB" Output: false

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ O(mn * 4^L) ๐Ÿช: O(mn)
๐Ÿ‡ Solution: MatrixPattern โฐ: O(n) ๐Ÿช: O(n)

var exist = function (board, word) {
let m = board.length;
let n = board[0].length;
let visited = new Array(m);
for (let i = 0; i < m; i++) {
visited[i] = new Array(n).fill(false);
}
let ๐ŸŒฒ DFS = (i, j, k) => {
if (i < 0 || i >= m || j < 0 || j >= n || visited[i][j] || board[i][j] !== word[k]) {
return false;
}
if (k === word.length - 1) {
return true;
}
visited[i][j] = true;
let result =
๐ŸŒฒ DFS(i + 1, j, k + 1) ||
๐ŸŒฒ DFS(i - 1, j, k + 1) ||
๐ŸŒฒ DFS(i, j + 1, k + 1) ||
๐ŸŒฒ DFS(i, j - 1, k + 1);
visited[i][j] = false;
return result;
};
for (let i = 0; i < m; i++) {
for (let j = 0; j < n; j++) {
if (๐ŸŒฒ DFS(i, j, 0)) {
return true;
}
}
}
return false;
};

---

## String

## [Valid Anagram](https://leetcode.com/problems/valid-anagram/) #242
โ“: Given two strings s & t , write a function to determine if t is an anagram of s.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "anagram", t = "nagaram" Output: true 2๏ธโƒฃ Input: s = "rat", t = "car" Output: false

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(nlogn) ๐Ÿช: O(n)
๐Ÿ‡ Solution: Hash Table โฐ: O(n) ๐Ÿช: O(n)

var isAnagram = function (s, t) {
if (s.length !== t.length) {
return false;
}
let map = new Map();
for (let i = 0; i < s.length; i++) {
map.set(s[i], (map.get(s[i]) || 0) + 1);
}
for (let i = 0; i < t.length; i++) {
if (!map.has(t[i])) {
return false;
}
map.set(t[i], map.get(t[i]) - 1);
if (map.get(t[i]) < 0) {
return false;
}
}
return true;
};
## [Group Anagrams](https://leetcode.com/problems/group-anagrams/) #49
โ“: Given an array of strings strs, group the anagrams together. You can return the answer in any order.
An Anagram is a word or phrase formed by rearranging the letters of a different word or phrase, typically using all the original letters exactly once.
๐Ÿฃ: 1๏ธโƒฃ Input: strs = ["eat","tea","tan","ate","nat","bat"] Output: [["bat"],["nat","tan"],["ate","eat","tea"]] 2๏ธโƒฃ Input: strs = [""] Output: [[""]] 3๏ธโƒฃ Input: strs = ["a"] Output: [["a"]]

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^2)
๐Ÿ‡ Solution: Hash Table โฐ: O(n) ๐Ÿช: O(n)

var groupAnagrams = function (strs) {
let map = new Map();
for (let i = 0; i < strs.length; i++) {
let sorted = strs[i].split("").sort().join("");
if (!map.has(sorted)) {
map.set(sorted, []);
}
map.get(sorted).push(strs[i]);
}
return [...map.values()];
};
## [Valid Parentheses](https://leetcode.com/problems/valid-parentheses/) #20
Pattern Used: Stack
โ“: Given a string s containing just the characters '(', ')', '{', '}', '[' & ']', determine if the input string is valid.
An input string is valid if:
Open brackets must be closed by the same type of brackets.
Open brackets must be closed in the correct order.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "()" Output: true 2๏ธโƒฃ Input: s = "()[]{}" Output: true 3๏ธโƒฃ Input: s = "(]" Output: false #4 Input: s = "([)]" Output: false #5 Input: s = "{[]}" Output: true

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^2) ๐Ÿช: O(n)
๐Ÿ‡ Solution: Stack โฐ: O(n) ๐Ÿช: O(n)

var isValid = function (s) {
let stack = [];
let map = new Map();
map.set("(", ")");
map.set("{", "}");
map.set("[", "]");
for (let i = 0; i < s.length; i++) {
if (map.has(s[i])) {
stack.push(s[i]);
} else {
if (map.get(stack.pop()) !== s[i]) {
return false;
}
}
}
return stack.length === 0;
};
## [Valid Palindrome](https://leetcode.com/problems/valid-palindrome/) #125 ๐Ÿ‘ฏ
โ“: Given a string s, determine if it is a palindrome, considering only alphanumeric characters & ignoring cases.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "A man, a plan, a canal: Panama" Output: true Explain: "amanaplanacanalpanama" is a palindrome.

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ:
๐Ÿ‡ Solution: ๐Ÿ‘ฏ Two Pointers โฐ:

var isPalindrome = function(s) {
let cursor1 = 0;
let cursor2 = s.length - 1;

while (cursor1 < cursor2) {
if (!(/^[a-zA-Z0-9]*$/.test(s[cursor1]))) {
cursor1++;
continue;
}
if (!(/^[a-zA-Z0-9]*$/.test(s[cursor2]))) {
cursor2--;
continue;
}
if (s[cursor1].toLowerCase() === s[cursor2].toLowerCase()) {
cursor1++;
cursor2--;
continue;
}
return false;
}

return true;
};

}
## [Longest Palindromic Substring](https://leetcode.com/problems/longest-palindromic-substring/) #5 ๐Ÿ“ˆ
โ“: Given a string s, return the longest palindromic substring in s.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "babad" Output: "bab" Note: "aba" is also a valid answer. 2๏ธโƒฃ Input: s = "cbbd" Output: "bb" 3๏ธโƒฃ Input: s = "a" Output: "a" #4 Input: s = "ac" Output: "a"

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^3) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming โฐ: O(n^2) ๐Ÿช: O(n^2)

var longestPalindrome = function (s) {
let result = "";
for (let i = 0; i < s.length; i++) {
let odd = exp&(s, i, i);
let even = exp&(s, i, i + 1);
let max = odd.length > even.length ? odd : even;
if (max.length > result.length) {
result = max;
}
}
return result;
};
function exp&(s, left, right) {
while (left >= 0 && right < s.length && s[left] === s[right]) {
left--;
right++;
}
return s.substring(left + 1, right);
}
## [Palindromic Substrings](https://leetcode.com/problems/palindromic-substrings/) #647 ๐Ÿ“ˆ
โ“: Given a string s, return the number of palindromic substrings in it.
A string is a palindrome when it reads the same backward as forward.
A substring is a contiguous sequence of characters within the string.
๐Ÿฃ: 1๏ธโƒฃ Input: s = "abc" Output: 3 Explain: Three palindromic strings: "a", "b", "c". 2๏ธโƒฃ Input: s = "aaa" Output: 6 Explain: Six palindromic strings: "a", "a", "a", "aa", "aa", "aaa".

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n^3) ๐Ÿช: O(1)
๐Ÿ‡ Solution: ๐Ÿ“ˆ Dynamic Programming โฐ: O(n^2) ๐Ÿช: O(n^2)

var countSubstrings = function (s) {
let count = 0;
for (let i = 0; i < s.length; i++) {
count += exp&(s, i, i);
count += exp&(s, i, i + 1);
}
return count;
};
function exp&(s, left, right) {
let count = 0;
while (left >= 0 && right < s.length && s[left] === s[right]) {
count++;
left--;
right++;
}
return count;
}

---

## Tree
## [Maximum Depth of Binary Tree](https://leetcode.com/problems/maximum-depth-of-binary-tree/)๐ŸŒฒ
โ“: Given the root of a binary tree, return its maximum depth.
A binary tree's maximum depth is the number of nodes along the longest path from the root node down to the farthest leaf node.
๐Ÿฃ: 1๏ธโƒฃ Input: root = [3,9,20,null,null,15,7] Output: 3 2๏ธโƒฃ Input: root = [1,null,2] Output: 2 3๏ธโƒฃ Input: root = [] Output: 0 #4 Input: root = [0] Output: 1

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐ŸŒฒ DFS โฐ: O(n) ๐Ÿช: O(n)

var maxDepth = function (root) {
if (!root) return 0;
return Math.max(maxDepth(root.left), maxDepth(root.right)) + 1;
};

## [Same Tree](https://leetcode.com/problems/same-tree/) #100๐ŸŒฒ
โ“: Given the roots of two binary trees p & q, write a function to check if they are the same or not.
Two binary trees are considered the same if they are structurally identical, & the nodes have the same value.
๐Ÿฃ: 1๏ธโƒฃ Input: p = [1,2,3], q = [1,2,3] Output: true 2๏ธโƒฃ Input: p = [1,2], q = [1,null,2] Output: false 3๏ธโƒฃ Input: p = [1,2,1], q = [1,1,2] Output: false

๐Ÿข Solution: ๐Ÿ”จ Brute Force โฐ: O(n) ๐Ÿช: O(n)
๐Ÿ‡ Solution: ๐ŸŒฒ DFS โฐ: O(n) ๐Ÿช: O(n)

var isSameTree = function (p, q) {
if (!p && !q) return true;
if (!p || !q) return false;
if (p.val !== q.val) return false;
return isSameTree(p.left, q.left) && isSameTree(p.right, q.right);
};

## [Invert/Flip Binary Tree](https://leetcode.com/problems/invert-binary-tree/) #226๐ŸŒฒ
โ“: Invert a binary tree.
๐Ÿฃ: 1๏ธโƒฃ Input: root = [4,2,7,1,3,6,9] Output: [4,7,2,9,6,3,1] 2๏ธโƒฃ Input: root = [2,1,3] Outpu