diff --git a/non-overlapping-intervals/uraflower.js b/non-overlapping-intervals/uraflower.js new file mode 100644 index 000000000..215fa1568 --- /dev/null +++ b/non-overlapping-intervals/uraflower.js @@ -0,0 +1,26 @@ +/** + * 구간이 겹치지 않게 하기 위해 최소한의 구간을 없애야 할 때, 몇 개를 없애야 하는지 반환하는 함수 + * @param {number[][]} intervals + * @return {number} + */ +const eraseOverlapIntervals = function(intervals) { + intervals.sort((a,b) => a[0] - b[0]); + + let count = 0; + let prevEnd = intervals[0][1]; + + for (let i = 1; i < intervals.length; i++) { + const [start, end] = intervals[i]; + + // 범위가 겹치는 경우 + if (prevEnd > start) { + count++; + prevEnd = Math.min(prevEnd, end); // end가 큰 걸 삭제한다 치기 + } + } + + return count; +}; + +// 시간복잡도: O(n * log n) +// 공간복잡도: O(1) diff --git a/number-of-connected-components-in-an-undirected-graph/uraflower.js b/number-of-connected-components-in-an-undirected-graph/uraflower.js new file mode 100644 index 000000000..15d2bcb3b --- /dev/null +++ b/number-of-connected-components-in-an-undirected-graph/uraflower.js @@ -0,0 +1,47 @@ + +/** + * @param n: the number of vertices + * @param edges: the edges of undirected graph + * @return: the number of connected components + */ +const countComponents = function (n, edges) { + // graph 만들기 + const graph = Array.from({ length: n }).map(() => []); + + for (const [u, v] of edges) { + graph[u].push(v); + graph[v].push(u); + } + + // 각 노드 순회하기 + let count = 0; + const visited = new Set(); + + for (let i = 0; i < n; i++) { + if (visited.has(i)) { + continue; + } + + count += 1; + + // bfs + const queue = [i]; + visited.add(i); + + while (queue.length) { + const u = queue.shift(); + + for (const v of graph[u]) { + if (!visited.has(v)) { + visited.add(v); + queue.push(v); + } + } + } + } + + return count; +} + +// 시간복잡도: O(E) +// 공간복잡도: O(V) diff --git a/remove-nth-node-from-end-of-list/uraflower.js b/remove-nth-node-from-end-of-list/uraflower.js new file mode 100644 index 000000000..317a94201 --- /dev/null +++ b/remove-nth-node-from-end-of-list/uraflower.js @@ -0,0 +1,59 @@ +/** + * Definition for singly-linked list. + * function ListNode(val, next) { + * this.val = (val===undefined ? 0 : val) + * this.next = (next===undefined ? null : next) + * } + */ + +// 첫 번째 풀이 +// 시간복잡도: O(n) +// 공간복잡도: O(n) +/** + * @param {ListNode} head + * @param {number} n + * @return {ListNode} + */ +const removeNthFromEnd = function (head, n) { + function dfs(node) { + // 마지막 노드이면 1 반환 + if (!node.next) { + return 1; + } + + const nth = dfs(node.next); + if (nth === n) { + node.next = node.next.next ?? null; + } + + return nth + 1; + } + + if (dfs(head) === n) { + return head.next; + } + + return head; +}; + +// 두 번째 풀이 +// 시간복잡도: O(n) +// 공간복잡도: O(1) +const removeNthFromEnd = function (head, n) { + const temp = new ListNode(0, head); + let tail = temp; + let prev = temp; // 뒤에서 n번째 노드 + + for (let i = 0; i < n; i++) { + tail = tail.next; + } + + while (tail.next) { + tail = tail.next; + prev = prev.next; + } + + prev.next = prev.next.next; + + return temp.next; +}; diff --git a/same-tree/uraflower.js b/same-tree/uraflower.js new file mode 100644 index 000000000..c8b4de433 --- /dev/null +++ b/same-tree/uraflower.js @@ -0,0 +1,20 @@ +/** + * 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} + */ +const isSameTree = function(p, q) { + if (!p && !q) return true; + return p?.val === q?.val && isSameTree(p.left, q.left) && isSameTree(p.right, q.right); +}; + +// 시간복잡도: O(n) +// 공간복잡도: O(h) (h: 트리의 높이, 즉 재귀 호출 스택) diff --git a/serialize-and-deserialize-binary-tree/uraflower.js b/serialize-and-deserialize-binary-tree/uraflower.js new file mode 100644 index 000000000..f662b8664 --- /dev/null +++ b/serialize-and-deserialize-binary-tree/uraflower.js @@ -0,0 +1,65 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +const NULL_SIGN = 'X'; + +/** + * Encodes a tree to a single string. + * 시간복잡도: O(n) + * 공간복잡도: O(h) (h: 재귀 스택 깊이 즉 트리 높이) + * @param {TreeNode} root + * @return {string} + */ +const serialize = function (root) { + const result = []; + + function traverse(root) { + result.push(root?.val ?? NULL_SIGN); + if (!root) { + return; + } + traverse(root.left); + traverse(root.right); + } + + traverse(root); + return result.join(','); +}; + +/** + * Decodes your encoded data to tree. + * 시간복잡도: O(n) + * 공간복잡도: O(h) (h: 재귀 스택 깊이 즉 트리 높이) + * @param {string} data + * @return {TreeNode} + */ +const deserialize = function (data) { + const splited = data.split(','); + let i = 0; + + function makeTree() { + if (splited[i] === NULL_SIGN) { + return null; + } + + const node = new TreeNode(Number(splited[i])); + i += 1; + node.left = makeTree(); + i += 1; + node.right = makeTree(); + + return node; + } + + return makeTree(); +}; + +/** + * Your functions will be called as such: + * deserialize(serialize(root)); + */