From faf630122d1687e69b07aef238ff9ad503bd8d02 Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Tue, 18 Mar 2025 06:27:36 +0900
Subject: [PATCH 1/4] feat: subtree-of-another-tree

---
 subtree-of-another-tree/gwbaik9717.js | 92 +++++++++++++++++++++++++++
 1 file changed, 92 insertions(+)
 create mode 100644 subtree-of-another-tree/gwbaik9717.js

diff --git a/subtree-of-another-tree/gwbaik9717.js b/subtree-of-another-tree/gwbaik9717.js
new file mode 100644
index 000000000..25af65218
--- /dev/null
+++ b/subtree-of-another-tree/gwbaik9717.js
@@ -0,0 +1,92 @@
+// n: number of nodes in root, m: number of nodes in subroot
+// Time complexity: O(n*m)
+// Space complexity: O(n)
+
+class _Queue {
+  constructor() {
+    this.q = [];
+    this.front = 0;
+    this.rear = 0;
+  }
+
+  isEmpty() {
+    return this.front === this.rear;
+  }
+
+  push(value) {
+    this.q.push(value);
+    this.rear++;
+  }
+
+  shift() {
+    const rv = this.q[this.front];
+    delete this.q[this.front++];
+    return rv;
+  }
+}
+/**
+ * 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
+ * @param {TreeNode} subRoot
+ * @return {boolean}
+ */
+var isSubtree = function (root, subRoot) {
+  const check = (root, subRoot) => {
+    const q = new _Queue();
+    q.push([root, subRoot]);
+
+    while (!q.isEmpty()) {
+      const [node, subNode] = q.shift();
+
+      if (node.val !== subNode.val) {
+        return false;
+      }
+
+      if ((node.left && !subNode.left) || (!node.left && subNode.left)) {
+        return false;
+      }
+
+      if ((node.right && !subNode.right) || (!node.right && subNode.right)) {
+        return false;
+      }
+
+      if (node.left && subNode.left) {
+        q.push([node.left, subNode.left]);
+      }
+
+      if (node.right && subNode.right) {
+        q.push([node.right, subNode.right]);
+      }
+    }
+
+    return true;
+  };
+
+  const q = new _Queue();
+  q.push(root);
+
+  while (!q.isEmpty()) {
+    const current = q.shift();
+
+    if (check(current, subRoot)) {
+      return true;
+    }
+
+    if (current.left) {
+      q.push(current.left);
+    }
+
+    if (current.right) {
+      q.push(current.right);
+    }
+  }
+
+  return false;
+};

From 23e0bfbca8a21d378f279ce67e0e7fd70d5d5262 Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Wed, 19 Mar 2025 06:46:05 +0900
Subject: [PATCH 2/4] feat: longest-palindromic-substring

---
 longest-palindromic-substring/gwbaik9717.js | 51 +++++++++++++++++++++
 1 file changed, 51 insertions(+)
 create mode 100644 longest-palindromic-substring/gwbaik9717.js

diff --git a/longest-palindromic-substring/gwbaik9717.js b/longest-palindromic-substring/gwbaik9717.js
new file mode 100644
index 000000000..78bc9e330
--- /dev/null
+++ b/longest-palindromic-substring/gwbaik9717.js
@@ -0,0 +1,51 @@
+// Time complexity: O(n^2)
+// Space complexity: O(n^2)
+
+/**
+ * @param {string} s
+ * @return {string}
+ */
+var longestPalindrome = function (s) {
+  const dp = Array.from({ length: s.length }, () =>
+    Array.from({ length: s.length }, () => false)
+  );
+
+  let answer = "";
+  let start = 0;
+  let end = 0;
+
+  const update = (i, j) => {
+    const newLen = Math.abs(i - j) + 1;
+
+    if (newLen > end - start + 1) {
+      start = i;
+      end = j;
+    }
+  };
+
+  for (let i = s.length - 1; i >= 0; i--) {
+    for (let j = i; j < s.length; j++) {
+      if (i === j) {
+        dp[i][j] = true;
+        update(i, j);
+        continue;
+      }
+
+      if (i + 1 === j) {
+        if (s[i] === s[j]) {
+          dp[i][j] = true;
+          update(i, j);
+        }
+
+        continue;
+      }
+
+      if (dp[i + 1][j - 1] && s[i] === s[j]) {
+        dp[i][j] = true;
+        update(i, j);
+      }
+    }
+  }
+
+  return s.slice(start, end + 1);
+};

From ed74fa0fb8768d07bfe92859138c5bcd1cc4a886 Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Thu, 20 Mar 2025 06:44:06 +0900
Subject: [PATCH 3/4] feat: Validate Binary Search Tree

---
 validate-binary-search-tree/gwbaik9717.js | 71 +++++++++++++++++++++++
 1 file changed, 71 insertions(+)
 create mode 100644 validate-binary-search-tree/gwbaik9717.js

diff --git a/validate-binary-search-tree/gwbaik9717.js b/validate-binary-search-tree/gwbaik9717.js
new file mode 100644
index 000000000..f1b8cf8b9
--- /dev/null
+++ b/validate-binary-search-tree/gwbaik9717.js
@@ -0,0 +1,71 @@
+// 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 {boolean}
+ */
+var isValidBST = function (root) {
+  const dfs = (root) => {
+    let minVal = root.val;
+    let maxVal = root.val;
+
+    if (root.left) {
+      if (root.left.val >= root.val) {
+        return false;
+      }
+
+      const result = dfs(root.left);
+
+      if (!result) {
+        return false;
+      }
+
+      const [min, max] = result;
+
+      if (max >= root.val) {
+        return false;
+      }
+
+      minVal = Math.min(minVal, min);
+      maxVal = Math.max(maxVal, max);
+    }
+
+    if (root.right) {
+      if (root.right.val <= root.val) {
+        return false;
+      }
+
+      const result = dfs(root.right);
+
+      if (!result) {
+        return false;
+      }
+
+      const [min, max] = result;
+
+      if (min <= root.val) {
+        return false;
+      }
+
+      minVal = Math.min(minVal, min);
+      maxVal = Math.max(maxVal, max);
+    }
+
+    return [minVal, maxVal];
+  };
+
+  if (dfs(root)) {
+    return true;
+  }
+
+  return false;
+};

From c16a29dcfee6d04982c66f4abddeead8b3142e93 Mon Sep 17 00:00:00 2001
From: ganu <gwbaik9717@icloud.com>
Date: Sat, 22 Mar 2025 07:49:27 +0900
Subject: [PATCH 4/4] feat: rotate-image

---
 rotate-image/gwbaik9717.js | 28 ++++++++++++++++++++++++++++
 1 file changed, 28 insertions(+)
 create mode 100644 rotate-image/gwbaik9717.js

diff --git a/rotate-image/gwbaik9717.js b/rotate-image/gwbaik9717.js
new file mode 100644
index 000000000..1c1cac3a1
--- /dev/null
+++ b/rotate-image/gwbaik9717.js
@@ -0,0 +1,28 @@
+// Time complexity: O(n^2)
+// Space complexity: O(1)
+
+/**
+ * @param {number[][]} matrix
+ * @return {void} Do not return anything, modify matrix in-place instead.
+ */
+var rotate = function (matrix) {
+  let top = 0;
+  let bottom = matrix.length - 1;
+
+  while (top < bottom) {
+    for (let i = 0; i < bottom - top; i++) {
+      const left = top;
+      const right = bottom;
+
+      const temp = matrix[top][left + i];
+
+      matrix[top][left + i] = matrix[bottom - i][left];
+      matrix[bottom - i][left] = matrix[bottom][right - i];
+      matrix[bottom][right - i] = matrix[top + i][right];
+      matrix[top + i][right] = temp;
+    }
+
+    top++;
+    bottom--;
+  }
+};