diff --git a/course-schedule/gwbaik9717.js b/course-schedule/gwbaik9717.js new file mode 100644 index 000000000..415a5017a --- /dev/null +++ b/course-schedule/gwbaik9717.js @@ -0,0 +1,68 @@ +// n: numCourses, p: len(prerequisites) +// Time complexity: O(n + p) +// Space complexity: O(n + p) + +class _Queue { + constructor() { + this.q = []; + this.start = 0; + this.end = 0; + } + + isEmpty() { + return this.start === this.end; + } + + push(value) { + this.q.push(value); + this.end++; + } + + shift() { + const rv = this.q[this.start]; + delete this.q[this.start++]; + + return rv; + } +} + +/** + * @param {number} numCourses + * @param {number[][]} prerequisites + * @return {boolean} + */ +var canFinish = function (numCourses, prerequisites) { + const graph = Array.from({ length: numCourses }, () => []); + const inDegree = Array.from({ length: numCourses }, () => 0); + + for (const [end, start] of prerequisites) { + graph[start].push(end); + inDegree[end]++; + } + + const q = new _Queue(); + + for (let i = 0; i < numCourses; i++) { + if (inDegree[i] === 0) { + q.push(i); + } + } + + let count = 0; + + while (!q.isEmpty()) { + const current = q.shift(); + count++; + + // 현재 노드와 연결된 다른 노드의 차수 감소 + for (const node of graph[current]) { + inDegree[node] -= 1; + + if (inDegree[node] === 0) { + q.push(node); + } + } + } + + return count === numCourses; +}; diff --git a/invert-binary-tree/gwbaik9717.js b/invert-binary-tree/gwbaik9717.js new file mode 100644 index 000000000..92d56d677 --- /dev/null +++ b/invert-binary-tree/gwbaik9717.js @@ -0,0 +1,33 @@ +// Time complexity: O(n) +// Space complexity: O(n) + +/** + * 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) + * } + */ +/** + * @param {TreeNode} root + * @return {TreeNode} + */ +var invertTree = function (root) { + const dfs = (current) => { + if (!current) { + return; + } + + const temp = current.left; + current.left = current.right; + current.right = temp; + + dfs(current.left); + dfs(current.right); + }; + + dfs(root); + + return root; +}; diff --git a/jump-game/gwbaik9717.js b/jump-game/gwbaik9717.js new file mode 100644 index 000000000..aa443a34b --- /dev/null +++ b/jump-game/gwbaik9717.js @@ -0,0 +1,28 @@ +// Time complexity: O(n) +// Space complexity: O(1) + +/** + * @param {number[]} nums + * @return {boolean} + */ +var canJump = function (nums) { + let maxValue = nums[0]; + + for (let i = 1; i < nums.length; i++) { + if (i > maxValue) { + return false; + } + + const newNum = i + nums[i]; + + if (newNum > maxValue) { + maxValue = newNum; + } + + if (maxValue >= nums.length - 1) { + break; + } + } + + return true; +}; diff --git a/merge-k-sorted-lists/gwbaik9717.js b/merge-k-sorted-lists/gwbaik9717.js new file mode 100644 index 000000000..eef4bcc0a --- /dev/null +++ b/merge-k-sorted-lists/gwbaik9717.js @@ -0,0 +1,134 @@ +// k: len(lists), n: Total number of nodes +// Time complexity: O(nlogk) +// Space complexity: O(n) + +class MinHeap { + constructor() { + this.heap = [null]; + } + + isEmpty() { + return this.heap.length === 1; + } + + push(listNode) { + this.heap.push(listNode); + + let current = this.heap.length - 1; + let parent = Math.floor(current / 2); + + while (parent !== 0) { + if (this.heap[parent].val > listNode.val) { + [this.heap[parent], this.heap[current]] = [ + this.heap[current], + this.heap[parent], + ]; + + current = parent; + parent = Math.floor(current / 2); + continue; + } + + break; + } + } + + pop() { + if (this.heap.length === 1) { + return; + } + + if (this.heap.length === 2) { + return this.heap.pop(); + } + + const rv = this.heap[1]; + + this.heap[1] = this.heap.pop(); + + let current = 1; + let left = current * 2; + let right = left + 1; + + while ( + (this.heap[left] && this.heap[current].val > this.heap[left].val) || + (this.heap[right] && this.heap[current].val > this.heap[right].val) + ) { + if (this.heap[left] && this.heap[right]) { + if (this.heap[left].val < this.heap[right].val) { + [this.heap[left], this.heap[current]] = [ + this.heap[current], + this.heap[left], + ]; + current = left; + } else { + [this.heap[right], this.heap[current]] = [ + this.heap[current], + this.heap[right], + ]; + current = right; + } + + left = current * 2; + right = left + 1; + continue; + } + + [this.heap[left], this.heap[current]] = [ + this.heap[current], + this.heap[left], + ]; + current = left; + left = current * 2; + right = left + 1; + } + + return rv; + } +} + +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode[]} lists + * @return {ListNode} + */ +var mergeKLists = function (lists) { + const minHeap = new MinHeap(); + + for (const list of lists) { + if (list) { + minHeap.push(list); + } + } + + let answer = null; + let next = null; + + while (!minHeap.isEmpty()) { + const current = minHeap.pop(); + + if (!answer) { + answer = new ListNode(); + next = answer; + } + + next.val = current.val; + + if (current.next) { + minHeap.push(current.next); + } + + if (!minHeap.isEmpty()) { + next.next = new ListNode(); + next = next.next; + } + } + + return answer; +}; diff --git a/search-in-rotated-sorted-array/gwbaik9717.js b/search-in-rotated-sorted-array/gwbaik9717.js new file mode 100644 index 000000000..cc42bdc79 --- /dev/null +++ b/search-in-rotated-sorted-array/gwbaik9717.js @@ -0,0 +1,40 @@ +// Time complexity: O(logn) +// Space complexity: O(1) + +/** + * @param {number[]} nums + * @param {number} target + * @return {number} + */ +var search = function (nums, target) { + let left = 0; + let right = nums.length - 1; + + while (left <= right) { + const mid = Math.floor((left + right) / 2); + + if (nums.at(mid) === target) { + return mid; + } + + // rotate 된 구간이 있을 때 + if (nums.at(mid + 1) > nums.at(right)) { + if (nums.at(right) >= target || nums.at(mid + 1) <= target) { + left = mid + 1; + continue; + } + + right = mid - 1; + continue; + } + + if (target >= nums.at(mid + 1) && target <= nums.at(right)) { + left = mid + 1; + continue; + } + + right = mid - 1; + } + + return -1; +};