Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
57 changes: 57 additions & 0 deletions canFinish.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,57 @@
/**
* @param {number} numCourses
* @param {number[][]} prerequisites
* @return {boolean}

Intuition:
I model courses as a directed graph where edges represent prerequisites.
I track how many prerequisites each course has using an in-degree array and store dependencies in an adjacency map.
Courses with in-degree `0` are added to a queue since they can be taken first. Using BFS, I process courses, reduce the in-degree of their dependents, and add new `0` in-degree courses to the queue.
If all courses are processed, there’s no cycle and we can finish; otherwise, a cycle exists.
T.C: O(V+E)
S.C: O(V+E)
*/
var canFinish = function (numCourses, prerequisites) {
// create in degree array
const inDegree = Array.from({
length: numCourses
}).fill(0);
// adj map to store parent and child relationship
let adjacencyMap = new Map();
for (let i = 0; i < prerequisites.length; i++) {
const [child, parent] = prerequisites[i];
inDegree[child]++;
if (adjacencyMap.has(parent)) {
const currList = adjacencyMap.get(parent);
currList.push(child);
} else {
adjacencyMap.set(parent, [child]);
}
};

const queue = [];
for (let i = 0; i < inDegree.length; i++) {
if (inDegree[i] === 0) {
queue.push(i);
}
}
// bfs
let idx = 0;
while (idx < queue.length) {
const currLength = queue.length - idx;
const course = queue[idx++];
const childs = adjacencyMap.get(course);
if (childs?.length) {
for (let j = 0; j < childs.length; j++) {
const child = childs[j];
// decrease the indegree as the parent is processed
inDegree[child]--;
// if the inDegree of a child is 0, add it to the queue.
if (inDegree[child] === 0) queue.push(child);
}

}
}
// if queue got all the courses that are given as input return true, oterwise false
return queue.length === numCourses;
};
38 changes: 38 additions & 0 deletions levelOrder.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/**
* Definition for a binary tree node.
* function TreeNode(val, left, right) {
* this.val = (val===undefined ? 0 : val)
* this.left = (left===undefined ? null : left)
* this.right = (right===undefined ? null : right)
* }
* Intuition:
* We perform a level-order traversal using a queue. Instead of removing elements with shift() (which is costly in JavaScript), we simulate the queue using an index pointer.
* The queue stores nodes level by level, and the index represents the current front of the queue. For each level, we calculate how many nodes belong to that level as queue.length - idx.
* We then process exactly those nodes, add their values to the result, and push their children to the queue.
* This way, every node is visited once, levels are clearly separated, and the traversal runs efficiently in linear time

T.C: O(n),
S.C: O(n)
*/
/**
* @param {TreeNode} root
* @return {number[][]}
*/
var levelOrder = function (root) {
const res = [];
if (!root) return res;
const queue = [root];
let idx = 0;
while (idx < queue.length) {
const currLevelNodes = [];
const currLength = queue.length - idx;
for (let i = 0; i < currLength; i++) {
const currRoot = queue[idx++];
currLevelNodes.push(currRoot.val);
if (currRoot.left) queue.push(currRoot.left);
if (currRoot.right) queue.push(currRoot.right);
}
res.push(currLevelNodes);
}
return res;
};