From 543425a3c31d6a08fc1f761193a8b3a76fc91cb2 Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Wed, 12 Mar 2025 09:01:26 +0900
Subject: [PATCH 1/5] feat: house-rober-ii

---
 house-robber-ii/gwbaik9717.js | 26 ++++++++++++++++++++++++++
 1 file changed, 26 insertions(+)
 create mode 100644 house-robber-ii/gwbaik9717.js

diff --git a/house-robber-ii/gwbaik9717.js b/house-robber-ii/gwbaik9717.js
new file mode 100644
index 000000000..12b069294
--- /dev/null
+++ b/house-robber-ii/gwbaik9717.js
@@ -0,0 +1,26 @@
+// Time complexity: O(n)
+// Space complexity: O(n)
+
+/**
+ * @param {number[]} nums
+ * @return {number}
+ */
+var rob = function (nums) {
+  if (nums.length === 1) {
+    return nums[0];
+  }
+
+  // include first
+  const dp1 = Array.from({ length: nums.length + 1 }, () => 0);
+  dp1[1] = nums[0];
+
+  // exclude first
+  const dp2 = Array.from({ length: nums.length + 1 }, () => 0);
+
+  for (let i = 2; i <= nums.length; i++) {
+    dp1[i] = Math.max(dp1[i - 2] + nums[i - 1], dp1[i - 1]);
+    dp2[i] = Math.max(dp2[i - 2] + nums[i - 1], dp2[i - 1]);
+  }
+
+  return Math.max(dp1.at(-2), dp2.at(-1));
+};

From 319ece1db4d08fb1d6d4a0b938d9a03db241be27 Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Thu, 13 Mar 2025 09:04:13 +0900
Subject: [PATCH 2/5] feat: word-search-ii

---
 word-search-ii/gwbaik9717.js | 79 ++++++++++++++++++++++++++++++++++++
 1 file changed, 79 insertions(+)
 create mode 100644 word-search-ii/gwbaik9717.js

diff --git a/word-search-ii/gwbaik9717.js b/word-search-ii/gwbaik9717.js
new file mode 100644
index 000000000..0ff3a15f2
--- /dev/null
+++ b/word-search-ii/gwbaik9717.js
@@ -0,0 +1,79 @@
+// n: length of words, k: length of word, h: height of board, w: width of board
+// Time complexity: O(4^k * h * w * n)
+// Space complexity: O(4^k)
+
+/**
+ * @param {character[][]} board
+ * @param {string[]} words
+ * @return {string[]}
+ */
+var findWords = function (board, words) {
+  const h = board.length;
+  const w = board[0].length;
+
+  const dy = [1, 0, -1, 0];
+  const dx = [0, 1, 0, -1];
+  const checked = Array.from({ length: h }, () =>
+    Array.from({ length: w }, () => false)
+  );
+
+  const findWord = (current, i, word) => {
+    const [cy, cx] = current;
+
+    if (i === word.length - 1) {
+      return true;
+    }
+
+    let found = false;
+
+    for (let j = 0; j < dx.length; j++) {
+      const nx = cx + dx[j];
+      const ny = cy + dy[j];
+
+      if (nx >= 0 && nx < w && ny >= 0 && ny < h && !checked[ny][nx]) {
+        if (board[ny][nx] === word[i + 1]) {
+          checked[ny][nx] = true;
+
+          if (findWord([ny, nx], i + 1, word)) {
+            found = true;
+          }
+
+          checked[ny][nx] = false;
+        }
+      }
+    }
+
+    return found;
+  };
+
+  const answer = [];
+
+  for (const word of words) {
+    let found = false;
+
+    for (let i = 0; i < h; i++) {
+      if (found) {
+        break;
+      }
+
+      for (let j = 0; j < w; j++) {
+        if (found) {
+          break;
+        }
+
+        if (board[i][j] === word[0]) {
+          checked[i][j] = true;
+
+          if (findWord([i, j], 0, word)) {
+            answer.push(word);
+            found = true;
+          }
+
+          checked[i][j] = false;
+        }
+      }
+    }
+  }
+
+  return answer;
+};

From 100154c7ae4cb1cc9ae6d261548882a25619a04f Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Fri, 14 Mar 2025 09:37:45 +0900
Subject: [PATCH 3/5] refactor: word-search-ii

---
 word-search-ii/gwbaik9717.js | 90 ++++++++++++++++++++----------------
 1 file changed, 49 insertions(+), 41 deletions(-)

diff --git a/word-search-ii/gwbaik9717.js b/word-search-ii/gwbaik9717.js
index 0ff3a15f2..bdc5217d1 100644
--- a/word-search-ii/gwbaik9717.js
+++ b/word-search-ii/gwbaik9717.js
@@ -1,13 +1,42 @@
-// n: length of words, k: length of word, h: height of board, w: width of board
-// Time complexity: O(4^k * h * w * n)
+// k: length of word, h: height of board, w: width of board
+// Time complexity: O(4^k * h * w)
 // Space complexity: O(4^k)
 
+class Node {
+  constructor(value = "") {
+    this.value = value;
+    this.children = new Map();
+    this.isEnd = false;
+  }
+}
+class Trie {
+  constructor() {
+    this.head = new Node();
+  }
+
+  add(str) {
+    let current = this.head;
+
+    for (const chr of str) {
+      if (!current.children.has(chr)) {
+        current.children.set(chr, new Node(current.value + chr));
+      }
+
+      current = current.children.get(chr);
+    }
+
+    current.isEnd = true;
+  }
+}
+
 /**
  * @param {character[][]} board
  * @param {string[]} words
  * @return {string[]}
  */
 var findWords = function (board, words) {
+  const answer = new Set();
+
   const h = board.length;
   const w = board[0].length;
 
@@ -17,63 +46,42 @@ var findWords = function (board, words) {
     Array.from({ length: w }, () => false)
   );
 
-  const findWord = (current, i, word) => {
+  const dfs = (current, children) => {
     const [cy, cx] = current;
 
-    if (i === word.length - 1) {
-      return true;
+    if (!children.has(board[cy][cx])) {
+      return;
     }
 
-    let found = false;
+    if (children.get(board[cy][cx]).isEnd) {
+      answer.add(children.get(board[cy][cx]).value);
+    }
 
     for (let j = 0; j < dx.length; j++) {
       const nx = cx + dx[j];
       const ny = cy + dy[j];
 
       if (nx >= 0 && nx < w && ny >= 0 && ny < h && !checked[ny][nx]) {
-        if (board[ny][nx] === word[i + 1]) {
-          checked[ny][nx] = true;
-
-          if (findWord([ny, nx], i + 1, word)) {
-            found = true;
-          }
-
-          checked[ny][nx] = false;
-        }
+        checked[ny][nx] = true;
+        dfs([ny, nx], children.get(board[cy][cx]).children);
+        checked[ny][nx] = false;
       }
     }
-
-    return found;
   };
 
-  const answer = [];
+  const trie = new Trie();
 
   for (const word of words) {
-    let found = false;
-
-    for (let i = 0; i < h; i++) {
-      if (found) {
-        break;
-      }
-
-      for (let j = 0; j < w; j++) {
-        if (found) {
-          break;
-        }
-
-        if (board[i][j] === word[0]) {
-          checked[i][j] = true;
-
-          if (findWord([i, j], 0, word)) {
-            answer.push(word);
-            found = true;
-          }
+    trie.add(word);
+  }
 
-          checked[i][j] = false;
-        }
-      }
+  for (let i = 0; i < h; i++) {
+    for (let j = 0; j < w; j++) {
+      checked[i][j] = true;
+      dfs([i, j], trie.head.children);
+      checked[i][j] = false;
     }
   }
 
-  return answer;
+  return [...answer];
 };

From f5b7405f69a34b0a22a71a98138ac56be1967f37 Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Sat, 15 Mar 2025 10:20:39 +0900
Subject: [PATCH 4/5] feat: Binary Tree Level Order Traversal

---
 .../gwbaik9717.js                             | 67 +++++++++++++++++++
 1 file changed, 67 insertions(+)
 create mode 100644 binary-tree-level-order-traversal/gwbaik9717.js

diff --git a/binary-tree-level-order-traversal/gwbaik9717.js b/binary-tree-level-order-traversal/gwbaik9717.js
new file mode 100644
index 000000000..4bfc40282
--- /dev/null
+++ b/binary-tree-level-order-traversal/gwbaik9717.js
@@ -0,0 +1,67 @@
+// n: number of nodes
+// Time complexity: O(n)
+// Space complexity: O(n)
+
+class _Queue {
+  constructor() {
+    this.q = [];
+    this.front = 0;
+    this.rear = 0;
+  }
+
+  push(value) {
+    this.q.push(value);
+    this.rear++;
+  }
+
+  shift() {
+    const rv = this.q[this.front];
+    delete this.q[this.front++];
+    return rv;
+  }
+
+  isEmpty() {
+    return this.front === this.rear;
+  }
+}
+
+/**
+ * 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 {number[][]}
+ */
+var levelOrder = function (root) {
+  const answer = [];
+  const q = new _Queue();
+
+  if (root) {
+    q.push([root, 0]);
+  }
+
+  while (!q.isEmpty()) {
+    const [current, lv] = q.shift();
+
+    if (answer.at(lv) === undefined) {
+      answer[lv] = [];
+    }
+
+    answer[lv].push(current.val);
+
+    if (current.left) {
+      q.push([current.left, lv + 1]);
+    }
+
+    if (current.right) {
+      q.push([current.right, lv + 1]);
+    }
+  }
+
+  return answer;
+};

From cec6d454628437b6dda871389c2f3ba2616a56c8 Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Sat, 15 Mar 2025 10:54:14 +0900
Subject: [PATCH 5/5] feat: counting bits

---
 counting-bits/gwbaik9717.js | 24 ++++++++++++++++++++++++
 1 file changed, 24 insertions(+)
 create mode 100644 counting-bits/gwbaik9717.js

diff --git a/counting-bits/gwbaik9717.js b/counting-bits/gwbaik9717.js
new file mode 100644
index 000000000..6a8681031
--- /dev/null
+++ b/counting-bits/gwbaik9717.js
@@ -0,0 +1,24 @@
+// Time complexity: O(n)
+// Space complexity: O(n)
+
+/**
+ * @param {number} n
+ * @return {number[]}
+ */
+var countBits = function (n) {
+  const dp = Array.from({ length: n + 1 }, () => 0);
+
+  if (n === 0) {
+    return dp;
+  }
+
+  dp[1] = 1;
+
+  for (let i = 2; i <= n; i++) {
+    const k = Math.floor(Math.log2(i));
+
+    dp[i] = 1 + dp[i - Math.pow(2, k)];
+  }
+
+  return dp;
+};