diff --git a/raejun/BalancedBinaryTree.js b/raejun/BalancedBinaryTree.js new file mode 100644 index 0000000..4e1db38 --- /dev/null +++ b/raejun/BalancedBinaryTree.js @@ -0,0 +1,59 @@ +/** + * 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 {boolean} + */ +var isBalanced = function (root) { + if (root === null) return true; + + let queue = [ + [root.left, "l"], + [root.right, "r"], + ]; + + let leftNullCnt = 0; + let rightNullCnt = 0; + + while (queue.length) { + const newQueue = []; + + for (let i = 0; i < queue.length; i++) { + if (queue[i][0] === null) continue; + + if (queue[i][0].left) { + newQueue.push([queue[i][0].left, queue[i][1]]); + } + + if (queue[i][0].right) { + newQueue.push([queue[i][0].right, queue[i][1]]); + } + } + + if (newQueue.every((v) => v[1] === "l")) rightNullCnt++; + if (newQueue.every((v) => v[1] === "r")) leftNullCnt++; + if (Math.abs(rightNullCnt - leftNullCnt) >= 2) return false; + + queue = newQueue; + } + + return true; +}; + +/* +문제 풀이 실패. + +시간 복잡도는 O(n)이다. n은 트리의 노드 수이다. + +BFS로 트리를 탐색하여 풀이하려고 하였다. + +문제 이해가 잘 안된다. 왼쪽과 오른쪽 차이가 1이란 게 루트에서 나오는 왼쪽과 오른쪽만 생각했다. +하지만, 트리의 모든 노드에서 왼쪽과 오른쪽 차이가 1이 되어야 한다는 조건으로 내가 푼 풀이에는 문제가 있다. + +*/ diff --git a/raejun/ImplementQueueusingStacks.js b/raejun/ImplementQueueusingStacks.js new file mode 100644 index 0000000..8478118 --- /dev/null +++ b/raejun/ImplementQueueusingStacks.js @@ -0,0 +1,74 @@ +var MyQueue = function () { + function ListNode(value) { + this.val = value ?? undefined; + this.next = null; + } + + this.getNode = function (v) { + return new ListNode(v); + }; + + this.node = new ListNode(undefined); + this.head = this.node; +}; + +/** + * @param {number} x + * @return {void} + */ +MyQueue.prototype.push = function (x) { + if (this.node.val === undefined) { + this.node.val = x; + } else { + const newNode = this.getNode(x); + + this.node.next = newNode; + } +}; + +/** + * @return {number} + */ +MyQueue.prototype.pop = function () { + const value = this.head.val; + + this.head = this.head.next; + + return value; +}; + +/** + * @return {number} + */ +MyQueue.prototype.peek = function () { + return this.head.val; +}; + +/** + * @return {boolean} + */ +MyQueue.prototype.empty = function () { + if (this.node === null) return true; + else return false; +}; + +/** + * Your MyQueue object will be instantiated and called as such: + * var obj = new MyQueue() + * obj.push(x) + * var param_2 = obj.pop() + * var param_3 = obj.peek() + * var param_4 = obj.empty() + */ + +/* +문제 풀지 못함. + +시간 복잡도는 push, pop, peek, empty 모두 O(1)이다. + +링크드 리스트를 이용하여 큐를 구현했다. + +링크드 리스트 문제를 풀면서 링크드 리스트로 구현을 하려고 했는데 실패했다. +문제에서 스택을 2개 사용하라고 했는데, 어떻게 스택을 이용해야 하는지 감이 잡히지 않았다. +당연히 Array의 매서드를 사용하면 안될 줄 알았는데 풀이를 보니 Array의 매서드를 사용해서 풀이하였다. +*/ diff --git a/raejun/LinkedListCycle.js b/raejun/LinkedListCycle.js new file mode 100644 index 0000000..c7f6f72 --- /dev/null +++ b/raejun/LinkedListCycle.js @@ -0,0 +1,32 @@ +/** + * Definition for singly-linked list. + * function ListNode(val) { + * this.val = val; + * this.next = null; + * } + */ + +/** + * @param {ListNode} head + * @return {boolean} + */ +var hasCycle = function (head) { + while (head !== null) { + if (head.val === "s") return true; + + head.val = "s"; + head = head.next; + } + + return false; +}; + +/* +13분 걸림. + +시간 복잡도는 O(n)이다. + +링크드 리스트를 탐색하면서 각 노드의 값을 's'로 바꿔주는 방식으로 풀이했다. 만약 이미 's'로 바뀐 노드를 만나면 사이클이 존재하는 것이다. + +노드의 값을 바꿔주는 방식이 다소 비효율적이긴 하지만, 다른 방법이 생각나지 않아 풀이했다. +*/ diff --git a/raejun/LowestCommonAncestorofaBinarySearchTree.js b/raejun/LowestCommonAncestorofaBinarySearchTree.js new file mode 100644 index 0000000..2362b5e --- /dev/null +++ b/raejun/LowestCommonAncestorofaBinarySearchTree.js @@ -0,0 +1,85 @@ +/** + * Definition for a binary tree node. + * function TreeNode(val) { + * this.val = val; + * this.left = this.right = null; + * } + */ + +/** + * @param {TreeNode} root + * @param {TreeNode} p + * @param {TreeNode} q + * @return {TreeNode} + */ +var lowestCommonAncestor = function (root, p, q) { + const findTarget = (root, target) => { + if (!root) return null; + + const queue = [[root, 0]]; + + while (queue.length) { + const [node, level] = queue.shift(); + + if (node === null) continue; + + if (node === target) return [node, level]; + + if (node.left) queue.push([node.left, level + 1]); + if (node.right) queue.push([node.right, level + 1]); + } + + return null; + }; + + const findParent = (root, target) => { + if (!root || root === target) return null; + + const queue = [root]; + + while (queue.length) { + const node = queue.shift(); + + if (node === null) continue; + + if (node.left) { + if (node.left === target) return node; + + queue.push(node.left); + } + if (node.right) { + if (node.right === target) return node; + + queue.push(node.right); + } + } + + return null; + }; + + let [pNode, pLevel] = findTarget(root, p); + let [qNode, qLevel] = findTarget(root, q); + + while (pNode !== qNode) { + if (pLevel <= qLevel) { + qNode = findParent(root, qNode); + qLevel -= 1; + } else { + pNode = findParent(root, pNode); + pLevel -= 1; + } + } + + return pNode; +}; + +/* +56분 걸림 + +시간 복잡도는 O(n2)이다. n은 트리의 노드 수이다. + +q, p의 위치를 찾는 함수와 부모를 찾는 함수를 만들어서 풀이했다. +q, p 중 더 높은 위치(더 깊은 노드)에 있는 노드를 부모로 이동시키는 방식으로 풀이했다. + +트리의 자식에서 부모로 가는 방법이 떠오르지 않았다. 그래서 따로 q, p의 위치를 찾고 부모를 찾는 함수를 만들어서 풀이했다. +*/