diff --git a/clone-graph/nhistory.js b/clone-graph/nhistory.js new file mode 100644 index 000000000..1cafc5dc4 --- /dev/null +++ b/clone-graph/nhistory.js @@ -0,0 +1,33 @@ +/** + * // Definition for a _Node. + * function _Node(val, neighbors) { + * this.val = val === undefined ? 0 : val; + * this.neighbors = neighbors === undefined ? [] : neighbors; + * }; + */ + +/** + * @param {_Node} node + * @return {_Node} + */ +var cloneGraph = function (node) { + let visited = {}; + + const dfs = (node) => { + if (!node) return node; + if (visited[node.val]) return visited[node.val]; + + let root = new Node(node.val); + visited[node.val] = root; + + for (let neighbor of node.neighbors) { + root.neighbors.push(dfs(neighbor)); + } + return root; + }; + + return dfs(node); +}; + +// TC: O(n+e) -> n: number of nodes | e: number of edges +// SC: O(v) -> v: length of visited object diff --git a/course-schedule/nhistory.js b/course-schedule/nhistory.js new file mode 100644 index 000000000..0acf8f3f4 --- /dev/null +++ b/course-schedule/nhistory.js @@ -0,0 +1,49 @@ +/** + * @param {number} numCourses + * @param {number[][]} prerequisites + * @return {boolean} + */ +var canFinish = function (numCourses, prerequisites) { + // Initialize in-degree array and graph map + const inDegree = Array(numCourses).fill(0); + const graph = new Map(); + + // Build the graph and compute in-degrees + prerequisites.forEach(([course, pre]) => { + inDegree[course]++; + if (!graph.has(pre)) { + graph.set(pre, []); + } + graph.get(pre).push(course); + }); + + // Queue for courses with no prerequisites + const queue = []; + for (let i = 0; i < numCourses; i++) { + if (inDegree[i] === 0) { + queue.push(i); + } + } + + // Process the courses + let count = 0; + while (queue.length > 0) { + const course = queue.shift(); + count++; + if (graph.has(course)) { + graph.get(course).forEach((nextCourse) => { + inDegree[nextCourse]--; + if (inDegree[nextCourse] === 0) { + queue.push(nextCourse); + } + }); + } + } + + // Return true if all courses can be finished + return count === numCourses; +}; + +// TC: O(V + E) +// V is the number of courses, E is the number of prerequisites. +// SC: O(V + E) diff --git a/design-add-and-search-words-data-structure/nhistory.js b/design-add-and-search-words-data-structure/nhistory.js new file mode 100644 index 000000000..bdcfd2410 --- /dev/null +++ b/design-add-and-search-words-data-structure/nhistory.js @@ -0,0 +1,37 @@ +var WordDictionary = function () { + this.dictionary = new Set(); +}; + +/** + * @param {string} word + * @return {void} + */ +WordDictionary.prototype.addWord = function (word) { + this.dictionary.add(word); +}; + +/** + * @param {string} word + * @return {boolean} + */ +WordDictionary.prototype.search = function (word) { + if (word.indexOf(".") != -1) { + // Case of word has a '.' + for (let str of this.dictionary) { + if (str.length != word.length) continue; + let i; + for (i = 0; i < word.length; i++) { + if (word[i] === ".") continue; + if (word[i] != str[i]) break; + } + if (i === str.length) return true; + } + return false; + } else { + return this.dictionary.has(word); + } +}; + +// n: number of words | m: length of the word +// TC: O(n*m) +// SC: O(n*m) diff --git a/number-of-islands/nhistory.js b/number-of-islands/nhistory.js new file mode 100644 index 000000000..694dff026 --- /dev/null +++ b/number-of-islands/nhistory.js @@ -0,0 +1,42 @@ +var numIslands = function (grid) { + // Declare row and column length + const m = grid.length, + n = grid[0].length; + let numIslands = 0; + + // Available directions for depth-first search + const dir = [ + [0, 1], + [1, 0], + [0, -1], + [-1, 0], + ]; + + // Function to depth-first search inside of grid + const dfs = (i, j) => { + grid[i][j] = "2"; + + let x, y; + for (d of dir) { + x = i + d[0]; + y = j + d[1]; + if (x >= 0 && x < m && y >= 0 && y < n && grid[x][y] === "1") { + dfs(x, y); + } + } + return; + }; + + for (let i = 0; i < m; i++) { + for (let j = 0; j < n; j++) { + if (grid[i][j] === "1") { + dfs(i, j); + numIslands++; + } + } + } + return numIslands; +}; + +// TC: O(m*n) +// SC: O(m*n) diff --git a/pacific-atlantic-water-flow/nhistory.js b/pacific-atlantic-water-flow/nhistory.js new file mode 100644 index 000000000..2b6b99d07 --- /dev/null +++ b/pacific-atlantic-water-flow/nhistory.js @@ -0,0 +1,63 @@ +/** + * @param {number[][]} heights + * @return {number[][]} + */ +var pacificAtlantic = function (heights) { + const m = heights.length, + n = heights[0].length; + let result = []; + + const pacific = new Array(m).fill(null).map(() => new Array(n).fill(false)); + const atlantic = new Array(m).fill(null).map(() => new Array(n).fill(false)); + + const dir = [ + [0, 1], + [1, 0], + [0, -1], + [-1, 0], + ]; + + const dfs = (i, j, ocean) => { + // Check visited cell + ocean[i][j] = true; + + for (d of dir) { + let x = i + d[0], + y = j + d[1]; + if ( + x >= 0 && + x < m && + y >= 0 && + y < n && + !ocean[x][y] && + heights[x][y] >= heights[i][j] + ) { + dfs(x, y, ocean); + } + } + }; + + // Check the cells can flow left and right edge + for (let i = 0; i < m; i++) { + dfs(i, 0, pacific); + dfs(i, n - 1, atlantic); + } + + // Check the cells can flow top and bottom edge + for (let j = 0; j < n; j++) { + dfs(0, j, pacific); + dfs(m - 1, j, atlantic); + } + + for (let i = 0; i < m; i++) { + for (let j = 0; j < n; j++) { + if (pacific[i][j] && atlantic[i][j]) { + result.push([i, j]); + } + } + } + return result; +}; + +// TC: O(m*n) +// SC: O(m*n)