diff --git a/find-minimum-in-rotated-sorted-array/mike2ox.ts b/find-minimum-in-rotated-sorted-array/mike2ox.ts
new file mode 100644
index 000000000..9e83b6340
--- /dev/null
+++ b/find-minimum-in-rotated-sorted-array/mike2ox.ts
@@ -0,0 +1,44 @@
+/**
+ * Source: https://leetcode.com/problems/find-minimum-in-rotated-sorted-array/
+ * 풀이방법: 이진 탐색을 이용하여 최솟값을 찾음
+ *
+ * 시간복잡도: O(log n)
+ * 공간복잡도: O(1)
+ */
+
+function findMin(nums: number[]): number {
+  // 배열의 길이가 1인 경우
+  if (nums.length === 1) return nums[0];
+
+  let left: number = 0;
+  let right: number = nums.length - 1;
+
+  // 이미 정렬된 경우
+  if (nums[right] > nums[0]) {
+    return nums[0];
+  }
+
+  // 이진 탐색
+  while (left <= right) {
+    const mid: number = Math.floor((left + right) / 2);
+
+    // 최솟값을 찾는 조건들
+    if (nums[mid] > nums[mid + 1]) {
+      return nums[mid + 1];
+    }
+    if (nums[mid - 1] > nums[mid]) {
+      return nums[mid];
+    }
+
+    // 탐색 범위 조정
+    if (nums[mid] > nums[0]) {
+      // 최솟값은 중간점 이후에 있음
+      left = mid + 1;
+    } else {
+      // 최솟값은 중간점 이전에 있음
+      right = mid - 1;
+    }
+  }
+
+  return nums[0]; // 기본값 반환
+}
diff --git a/linked-list-cycle/mike2ox.ts b/linked-list-cycle/mike2ox.ts
new file mode 100644
index 000000000..bf4ac00f2
--- /dev/null
+++ b/linked-list-cycle/mike2ox.ts
@@ -0,0 +1,39 @@
+/**
+ * Source: https://leetcode.com/problems/linked-list-cycle/
+ * 풀이방법: Set을 이용하여 방문한 노드를 저장하고 순회하면서 중복된 노드가 있는지 확인
+ *
+ * 시간복잡도: O(n)
+ * 공간복잡도: O(n)
+ */
+
+// class ListNode {
+//   val: number;
+//   next: ListNode | null;
+//   constructor(val?: number, next?: ListNode | null) {
+//     this.val = val === undefined ? 0 : val;
+//     this.next = next === undefined ? null : next;
+//   }
+// }
+
+function hasCycle(head: ListNode | null): boolean {
+  if (head === null) return false;
+
+  // 방문한 노드들을 저장할 Set
+  const addr = new Set<ListNode>();
+
+  // 첫 노드 추가
+  addr.add(head);
+  head = head.next;
+
+  // 리스트 순회
+  while (head !== null) {
+    // 이미 방문한 노드인 경우 cycle 존재
+    if (addr.has(head)) return true;
+
+    // 새로운 노드 추가
+    addr.add(head);
+    head = head.next;
+  }
+
+  return false;
+}
diff --git a/maximum-product-subarray/mike2ox.ts b/maximum-product-subarray/mike2ox.ts
new file mode 100644
index 000000000..886318a46
--- /dev/null
+++ b/maximum-product-subarray/mike2ox.ts
@@ -0,0 +1,40 @@
+/**
+ * Source: https://leetcode.com/problems/maximum-product-subarray/
+ * 풀이방법: 현재 곱과 최대 곱을 비교하여 최대값을 구함
+ *
+ * 시간복잡도: O(n)
+ * 공간복잡도: O(1)
+ *
+ * 다른 풀이방법
+ * - DP를 이용하여 풀이
+ */
+function maxProduct(nums: number[]): number {
+  if (nums.length === 0) return 0;
+
+  let maxProduct = nums[0];
+  let currentProduct = 1;
+
+  // 왼쪽에서 오른쪽으로 순회
+  for (let i = 0; i < nums.length; i++) {
+    currentProduct *= nums[i];
+    maxProduct = Math.max(maxProduct, currentProduct);
+    // 현재 곱이 0이 되면 리셋
+    if (currentProduct === 0) {
+      currentProduct = 1;
+    }
+  }
+
+  currentProduct = 1;
+
+  // 오른쪽에서 왼쪽으로 순회
+  for (let i = nums.length - 1; i >= 0; i--) {
+    currentProduct *= nums[i];
+    maxProduct = Math.max(maxProduct, currentProduct);
+    // 현재 곱이 0이 되면 리셋
+    if (currentProduct === 0) {
+      currentProduct = 1;
+    }
+  }
+
+  return maxProduct;
+}
diff --git a/pacific-atlantic-water-flow/mike2ox.ts b/pacific-atlantic-water-flow/mike2ox.ts
new file mode 100644
index 000000000..1a3374b43
--- /dev/null
+++ b/pacific-atlantic-water-flow/mike2ox.ts
@@ -0,0 +1,75 @@
+/**
+ * Source: https://leetcode.com/problems/pacific-atlantic-water-flow/
+ * 풀이방법: DFS를 이용하여 pacific과 atlantic에서 물이 흐르는 지점을 찾음
+ *
+ * 시간복잡도: O(n * m) (n: 행의 개수, m: 열의 개수)
+ * 공간복잡도: O(n * m)
+ */
+
+function pacificAtlantic(heights: number[][]): number[][] {
+  if (!heights || !heights[0]) return [];
+
+  const rows = heights.length;
+  const cols = heights[0].length;
+
+  // checklist
+  const pacific = new Set<string>();
+  const atlantic = new Set<string>();
+
+  // DFS
+  function dfs(
+    row: number,
+    col: number,
+    prevHeight: number,
+    visited: Set<string>
+  ) {
+    // row, col이 경계 밖이거나 이미 방문했거나 이전 높이보다 낮은 경우
+    if (
+      row < 0 ||
+      row >= rows ||
+      col < 0 ||
+      col >= cols ||
+      heights[row][col] < prevHeight ||
+      visited.has(`${row},${col}`)
+    ) {
+      return;
+    }
+
+    // 현재 위치 체크
+    visited.add(`${row},${col}`);
+
+    // 4방향 탐색
+    dfs(row + 1, col, heights[row][col], visited);
+    dfs(row - 1, col, heights[row][col], visited);
+    dfs(row, col + 1, heights[row][col], visited);
+    dfs(row, col - 1, heights[row][col], visited);
+  }
+
+  // 0,0에서부터 탐색 시작
+  for (let col = 0; col < cols; col++) {
+    dfs(0, col, heights[0][col], pacific);
+  }
+  for (let row = 0; row < rows; row++) {
+    dfs(row, 0, heights[row][0], pacific);
+  }
+
+  // rows-1, cols-1(pacific하고는 정반대 위치에서 시작)
+  for (let col = 0; col < cols; col++) {
+    dfs(rows - 1, col, heights[rows - 1][col], atlantic);
+  }
+  for (let row = 0; row < rows; row++) {
+    dfs(row, cols - 1, heights[row][cols - 1], atlantic);
+  }
+
+  const result: number[][] = [];
+  for (let row = 0; row < rows; row++) {
+    for (let col = 0; col < cols; col++) {
+      const pos = `${row},${col}`;
+      if (pacific.has(pos) && atlantic.has(pos)) {
+        result.push([row, col]);
+      }
+    }
+  }
+
+  return result;
+}