From 313582fda568ee6f2d6c6ec6c3ded9573344b215 Mon Sep 17 00:00:00 2001 From: RamKuppagiri Date: Sat, 24 Jan 2026 15:09:43 -0600 Subject: [PATCH] bfs-1 --- canFinish.js | 57 +++++++++++++++++++++++++++++++++++++++++++++++++++ levelOrder.js | 38 ++++++++++++++++++++++++++++++++++ 2 files changed, 95 insertions(+) create mode 100644 canFinish.js create mode 100644 levelOrder.js diff --git a/canFinish.js b/canFinish.js new file mode 100644 index 00000000..2ae07701 --- /dev/null +++ b/canFinish.js @@ -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; +}; \ No newline at end of file diff --git a/levelOrder.js b/levelOrder.js new file mode 100644 index 00000000..dfad907e --- /dev/null +++ b/levelOrder.js @@ -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; +}; \ No newline at end of file