From bf5a3c688e26b0fc93bca86949cf7fbdd47b55f5 Mon Sep 17 00:00:00 2001 From: ganu Date: Mon, 24 Feb 2025 09:09:45 +0900 Subject: [PATCH 1/6] feat: 100. Same Tree --- same-tree/gwbaik9717.js | 62 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 62 insertions(+) create mode 100644 same-tree/gwbaik9717.js diff --git a/same-tree/gwbaik9717.js b/same-tree/gwbaik9717.js new file mode 100644 index 000000000..65ec64a2a --- /dev/null +++ b/same-tree/gwbaik9717.js @@ -0,0 +1,62 @@ +// n: number of nodes +// 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} p + * @param {TreeNode} q + * @return {boolean} + */ +var isSameTree = function (p, q) { + const dfs = (currentP, currentQ) => { + if (currentP.val !== currentQ.val) { + return false; + } + + if ( + (currentP.left && !currentQ.left) || + (!currentP.left && currentQ.left) + ) { + return false; + } + + if ( + (currentP.right && !currentQ.right) || + (!currentP.right && currentQ.right) + ) { + return false; + } + + if (currentP.left && currentQ.left) { + if (!dfs(currentP.left, currentQ.left)) { + return false; + } + } + + if (currentP.right && currentQ.right) { + if (!dfs(currentP.right, currentQ.right)) { + return false; + } + } + + return true; + }; + + if ((p && !q) || (!p && q)) { + return false; + } + + if (p && q) { + return dfs(p, q); + } + + return true; +}; From 35459a32cfc7f2b92e4952837c9ef8f2c14a49d5 Mon Sep 17 00:00:00 2001 From: ganu Date: Mon, 24 Feb 2025 09:18:36 +0900 Subject: [PATCH 2/6] refactor: 100. Same Tree --- same-tree/gwbaik9717.js | 40 ++++++++-------------------------------- 1 file changed, 8 insertions(+), 32 deletions(-) diff --git a/same-tree/gwbaik9717.js b/same-tree/gwbaik9717.js index 65ec64a2a..56ebcf505 100644 --- a/same-tree/gwbaik9717.js +++ b/same-tree/gwbaik9717.js @@ -17,46 +17,22 @@ */ var isSameTree = function (p, q) { const dfs = (currentP, currentQ) => { - if (currentP.val !== currentQ.val) { - return false; + if (!currentP && !currentQ) { + return true; } - if ( - (currentP.left && !currentQ.left) || - (!currentP.left && currentQ.left) - ) { + if ((!currentP && currentQ) || (currentP && !currentQ)) { return false; } - if ( - (currentP.right && !currentQ.right) || - (!currentP.right && currentQ.right) - ) { + if (currentP.val !== currentQ.val) { return false; } - if (currentP.left && currentQ.left) { - if (!dfs(currentP.left, currentQ.left)) { - return false; - } - } - - if (currentP.right && currentQ.right) { - if (!dfs(currentP.right, currentQ.right)) { - return false; - } - } - - return true; + return ( + dfs(currentP.left, currentQ.left) && dfs(currentP.right, currentQ.right) + ); }; - if ((p && !q) || (!p && q)) { - return false; - } - - if (p && q) { - return dfs(p, q); - } - - return true; + return dfs(p, q); }; From 018a2de78a045ce1ebf5aec7b0c01637650187c4 Mon Sep 17 00:00:00 2001 From: ganu Date: Wed, 26 Feb 2025 09:42:55 +0900 Subject: [PATCH 3/6] feat: 19. Remove Nth Node From End of List --- .../gwbaik9717.js | 50 +++++++++++++++++++ 1 file changed, 50 insertions(+) create mode 100644 remove-nth-node-from-end-of-list/gwbaik9717.js diff --git a/remove-nth-node-from-end-of-list/gwbaik9717.js b/remove-nth-node-from-end-of-list/gwbaik9717.js new file mode 100644 index 000000000..4efdeb541 --- /dev/null +++ b/remove-nth-node-from-end-of-list/gwbaik9717.js @@ -0,0 +1,50 @@ +// Time complexity: O(n) +// Space complexity: O(1) + +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ +/** + * @param {ListNode} head + * @param {number} n + * @return {ListNode} + */ +var removeNthFromEnd = function (head, n) { + const reverse = (head) => { + let next = null; + let current = head; + + while (current) { + const temp = current.next; + current.next = next; + next = current; + current = temp; + } + + return next; + }; + + // Reverse + let reversedHead = reverse(head); + + if (n === 1) { + reversedHead = reversedHead.next; + } else { + let prev = null; + let current = reversedHead; + + for (let i = 1; i < n; i++) { + prev = current; + current = current.next; + } + + prev.next = current.next; + } + + // Reverse Again + return reverse(reversedHead); +}; From 44397eff840a812f093e9f7533eaacbef80ef08e Mon Sep 17 00:00:00 2001 From: ganu Date: Thu, 27 Feb 2025 06:57:34 +0900 Subject: [PATCH 4/6] feat: non-overlapping-intervals --- non-overlapping-intervals/gwbaik9717.js | 47 +++++++++++++++++++++++++ 1 file changed, 47 insertions(+) create mode 100644 non-overlapping-intervals/gwbaik9717.js diff --git a/non-overlapping-intervals/gwbaik9717.js b/non-overlapping-intervals/gwbaik9717.js new file mode 100644 index 000000000..bd52558ff --- /dev/null +++ b/non-overlapping-intervals/gwbaik9717.js @@ -0,0 +1,47 @@ +// Time complexity: O(n^2) +// Space complexity: O(n) + +/** + * @param {number[][]} intervals + * @return {number} + */ +var eraseOverlapIntervals = function (intervals) { + intervals.sort((a, b) => { + if (a[0] === b[0]) { + return a[1] - b[1]; + } + + return a[0] - b[0]; + }); + + const dp = Array.from({ length: intervals.length }, () => 0); + + dp[0] = 1; + + for (let i = 1; i < intervals.length; i++) { + const [prevStart, prevEnd] = intervals[i - 1]; + const [currentStart, currentEnd] = intervals[i]; + + // 구간이 겹칠 때 + if (currentStart < prevEnd) { + // 현재를 포함할 때 + let maxValue = 1; + for (let j = i - 1; j >= 0; j--) { + const [start, end] = intervals[j]; + + if (end <= currentStart) { + maxValue += dp[j]; + break; + } + } + + dp[i] = Math.max(dp[i - 1], maxValue); + continue; + } + + // 구간이 겹치지 않을 때 + dp[i] = dp[i - 1] + 1; + } + + return intervals.length - dp.at(-1); +}; From dd1ff50cb4bf9ff9631f3b8394ec0754e788d66f Mon Sep 17 00:00:00 2001 From: ganu Date: Thu, 27 Feb 2025 07:10:56 +0900 Subject: [PATCH 5/6] refactor: non-overlapping-intervals --- non-overlapping-intervals/gwbaik9717.js | 32 ++++++++----------------- 1 file changed, 10 insertions(+), 22 deletions(-) diff --git a/non-overlapping-intervals/gwbaik9717.js b/non-overlapping-intervals/gwbaik9717.js index bd52558ff..3eb5bcd2e 100644 --- a/non-overlapping-intervals/gwbaik9717.js +++ b/non-overlapping-intervals/gwbaik9717.js @@ -1,5 +1,5 @@ -// Time complexity: O(n^2) -// Space complexity: O(n) +// Time complexity: O(nlogn) +// Space complexity: O(1) /** * @param {number[][]} intervals @@ -14,34 +14,22 @@ var eraseOverlapIntervals = function (intervals) { return a[0] - b[0]; }); - const dp = Array.from({ length: intervals.length }, () => 0); - - dp[0] = 1; + let count = 0; + let prevEnd = intervals[0][1]; for (let i = 1; i < intervals.length; i++) { - const [prevStart, prevEnd] = intervals[i - 1]; - const [currentStart, currentEnd] = intervals[i]; + const [start, end] = intervals[i]; // 구간이 겹칠 때 - if (currentStart < prevEnd) { - // 현재를 포함할 때 - let maxValue = 1; - for (let j = i - 1; j >= 0; j--) { - const [start, end] = intervals[j]; - - if (end <= currentStart) { - maxValue += dp[j]; - break; - } - } - - dp[i] = Math.max(dp[i - 1], maxValue); + if (prevEnd > start) { + count++; + prevEnd = Math.min(prevEnd, end); continue; } // 구간이 겹치지 않을 때 - dp[i] = dp[i - 1] + 1; + prevEnd = end; } - return intervals.length - dp.at(-1); + return count; }; From 77309a47d0ff30612b2075be8a9a6372054f9e5d Mon Sep 17 00:00:00 2001 From: ganu Date: Sat, 1 Mar 2025 10:18:12 +0900 Subject: [PATCH 6/6] feat: 297. Serialize and Deserialize Binary Tree --- .../gwbaik9717.js | 132 ++++++++++++++++++ 1 file changed, 132 insertions(+) create mode 100644 serialize-and-deserialize-binary-tree/gwbaik9717.js diff --git a/serialize-and-deserialize-binary-tree/gwbaik9717.js b/serialize-and-deserialize-binary-tree/gwbaik9717.js new file mode 100644 index 000000000..6237078f3 --- /dev/null +++ b/serialize-and-deserialize-binary-tree/gwbaik9717.js @@ -0,0 +1,132 @@ +// n: number of nodes, h: height of tree (max: n) +// Time complexity: O(n) +// Space complexity: O(2^h) + +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +class _Queue { + constructor() { + this.q = []; + this.left = 0; + this.right = 0; + } + + push(value) { + this.q.push(value); + this.right++; + } + + shift() { + const rv = this.q[this.left]; + delete this.q[this.left++]; + + return rv; + } + + isEmpty() { + return this.left === this.right; + } +} + +const isValid = (data) => { + if (data === undefined || data === null) { + return false; + } + + return true; +}; + +/** + * Encodes a tree to a single string. + * + * @param {TreeNode} root + * @return {string} + */ +var serialize = function (root) { + const answer = [null]; + + const bfs = (current) => { + const q = new _Queue(); + q.push([1, current]); + + while (!q.isEmpty()) { + const [i, current] = q.shift(); + + if (current === null) { + answer[i] = current; + continue; + } + + answer[i] = current.val; + + const left = 2 * i; + const right = left + 1; + + if (current.left) { + q.push([left, current.left]); + } else { + q.push([left, null]); + } + + if (current.right) { + q.push([right, current.right]); + } else { + q.push([right, null]); + } + } + }; + + bfs(root); + + while (answer.length > 1 && !isValid(answer.at(-1))) { + answer.pop(); + } + + return answer; +}; + +/** + * Decodes your encoded data to tree. + * + * @param {string} data + * @return {TreeNode} + */ +var deserialize = function (data) { + if (data.length === 1) { + return null; + } + + const root = new TreeNode(data[1]); + const q = new _Queue(); + q.push([1, root]); + + while (!q.isEmpty()) { + const [i, current] = q.shift(); + + const left = i * 2; + const right = left + 1; + + if (left <= data.length && isValid(data[left])) { + current.left = new TreeNode(data[left]); + q.push([left, current.left]); + } + + if (right <= data.length && isValid(data[right])) { + current.right = new TreeNode(data[right]); + q.push([right, current.right]); + } + } + + return root; +}; + +/** + * Your functions will be called as such: + * deserialize(serialize(root)); + */