From a0cc74638fc516bec91e28b62eb5a1fd2767b33a Mon Sep 17 00:00:00 2001 From: HC-kang Date: Mon, 7 Oct 2024 08:26:37 +0900 Subject: [PATCH 1/5] Feat: 141. Linked List Cycle --- linked-list-cycle/HC-kang.ts | 42 ++++++++++++++++++++++++++++++++++++ 1 file changed, 42 insertions(+) create mode 100644 linked-list-cycle/HC-kang.ts diff --git a/linked-list-cycle/HC-kang.ts b/linked-list-cycle/HC-kang.ts new file mode 100644 index 000000000..0ab290ab6 --- /dev/null +++ b/linked-list-cycle/HC-kang.ts @@ -0,0 +1,42 @@ +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; + } +} + +/** + * https://leetcode.com/problems/linked-list-cycle + * T.C. O(n) + * S.C. O(n) + */ +function hasCycle(head: ListNode | null): boolean { + const SET = new Set(); + while (head) { + if (SET.has(head)) return true; + SET.add(head); + head = head.next + } + return false; +}; + +/** + * T.C. O(n) + * S.C. O(1) + */ +function hasCycle(head: ListNode | null): boolean { + let fast = head; + let slow = head; + + while (fast && fast.next) { + fast = fast.next.next; + slow = slow!.next; + + if (fast === slow) { + return true; + } + } + return false; +}; From 9a46c55c758575aa4a40782aaf2c9d8551868d87 Mon Sep 17 00:00:00 2001 From: HC-kang Date: Wed, 9 Oct 2024 14:07:05 +0900 Subject: [PATCH 2/5] Feat: 153. Find Minimum in Rotated Sorted Array --- .../HC-kang.ts | 20 +++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 find-minimum-in-rotated-sorted-array/HC-kang.ts diff --git a/find-minimum-in-rotated-sorted-array/HC-kang.ts b/find-minimum-in-rotated-sorted-array/HC-kang.ts new file mode 100644 index 000000000..88789b752 --- /dev/null +++ b/find-minimum-in-rotated-sorted-array/HC-kang.ts @@ -0,0 +1,20 @@ +/** + * https://leetcode.com/problems/find-minimum-in-rotated-sorted-array + * T.C. O(log n) + * S.C. O(1) + */ +function findMin(nums: number[]): number { + let left = 0; + let right = nums.length - 1; + let mid = (left + right) >> 1; + + while (left < right) { + if (nums[mid] > nums[right]) { + left = mid + 1; + } else { + right = mid; + } + mid = (left + right) >> 1; + } + return nums[left]; +} From aff0d63682dd5de57788bd8ffb2b9feb94cf1515 Mon Sep 17 00:00:00 2001 From: HC-kang Date: Wed, 9 Oct 2024 15:25:07 +0900 Subject: [PATCH 3/5] Feat: 53. Maximum Subarray --- maximum-subarray/HC-kang.ts | 93 +++++++++++++++++++++++++++++++++++++ 1 file changed, 93 insertions(+) create mode 100644 maximum-subarray/HC-kang.ts diff --git a/maximum-subarray/HC-kang.ts b/maximum-subarray/HC-kang.ts new file mode 100644 index 000000000..9ba943962 --- /dev/null +++ b/maximum-subarray/HC-kang.ts @@ -0,0 +1,93 @@ +/** + * https://leetcode.com/problems/maximum-subarray + * Kadane's Algorithm + * T.C. O(n) + * S.C. O(1) + */ +function maxSubArray(nums: number[]): number { + let maxSum = nums[0]; + + for (let i = 1; i < nums.length; i++) { + nums[i] = Math.max(nums[i], nums[i] + nums[i - 1]); + maxSum = Math.max(maxSum, nums[i]); + } + + return maxSum; +} + +/** + * Divide and Conquer version + * T.C. O(n log n) + * S.C. O(log n) - call stack + */ +function maxSubArray(nums: number[]): number { + function maxSubArrayHelper( + nums: number[], + left: number, + right: number + ): number { + if (left === right) return nums[left]; + + const mid = (left + right) >> 1; + const leftMax = maxSubArrayHelper(nums, left, mid); + const rightMax = maxSubArrayHelper(nums, mid + 1, right); + let leftSum = -Infinity; + let rightSum = -Infinity; + let sum = 0; + + for (let i = mid; i >= left; i--) { + sum += nums[i]; + leftSum = Math.max(leftSum, sum); + } + + sum = 0; + for (let i = mid + 1; i <= right; i++) { + sum += nums[i]; + rightSum = Math.max(rightSum, sum); + } + + return Math.max(leftMax, rightMax, leftSum + rightSum); + } + + return maxSubArrayHelper(nums, 0, nums.length - 1); +} + +/** + * Iterative version + * T.C. O(n log n) + * S.C. O(log n) - call stack + */ +function maxSubArray(nums: number[]): number { + const stack = [[0, nums.length - 1]]; + let maxSum = nums[0]; + + while (stack.length) { + const [left, right] = stack.pop()!; + if (left === right) { + maxSum = Math.max(maxSum, nums[left]); + continue; + } + + const mid = (left + right) >> 1; + stack.push([left, mid], [mid + 1, right]); + + let leftSum = -Infinity; + let rightSum = -Infinity; + let sum = 0; + + for (let i = mid; i >= left; i--) { + sum += nums[i]; + leftSum = Math.max(leftSum, sum); + } + + sum = 0; + for (let i = mid + 1; i <= right; i++) { + sum += nums[i]; + rightSum = Math.max(rightSum, sum); + } + + maxSum = Math.max(maxSum, leftSum + rightSum); + } + + return maxSum; +} From cd17daa59a761f233519c67ee4ce0828cdc60112 Mon Sep 17 00:00:00 2001 From: HC-kang Date: Wed, 9 Oct 2024 16:08:07 +0900 Subject: [PATCH 4/5] Feat: 76. Minimum Window Substring --- minimum-window-substring/HC-kang.ts | 44 +++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) create mode 100644 minimum-window-substring/HC-kang.ts diff --git a/minimum-window-substring/HC-kang.ts b/minimum-window-substring/HC-kang.ts new file mode 100644 index 000000000..df4c4fbdb --- /dev/null +++ b/minimum-window-substring/HC-kang.ts @@ -0,0 +1,44 @@ +/** + * https://leetcode.com/problems/minimum-window-substring + * T.C. O(s + t) + * S.C. O(t) + */ +function minWindow(s: string, t: string): string { + let minLow = 0; + let minHigh = s.length; + + const counts: Record = {}; + for (const c of t) { + counts[c] = (counts[c] || 0) + 1; + } + + let included = 0; + + let low = 0; + for (let high = 0; high < s.length; high++) { + if (counts[s[high]]) { + if (counts[s[high]] > 0) { + included++; + } + counts[s[high]]--; + } + + while (included === t.length) { + if (high - low < minHigh - minLow) { + minLow = low; + minHigh = high; + } + + if (counts[s[low]]) { + counts[s[low]]++; + if (counts[s[low]] > 0) { + included--; + } + } + + low++; + } + } + + return minHigh === s.length ? '' : s.substring(minLow, minHigh + 1); +} From 5d0a623fafe8a1c7c1d956042b9f7d6df180027f Mon Sep 17 00:00:00 2001 From: HC-kang Date: Thu, 10 Oct 2024 08:38:22 +0900 Subject: [PATCH 5/5] Feat: 417. Pacific Atlantic Water Flow --- pacific-atlantic-water-flow/HC-kang.ts | 115 +++++++++++++++++++++++++ 1 file changed, 115 insertions(+) create mode 100644 pacific-atlantic-water-flow/HC-kang.ts diff --git a/pacific-atlantic-water-flow/HC-kang.ts b/pacific-atlantic-water-flow/HC-kang.ts new file mode 100644 index 000000000..303593a9e --- /dev/null +++ b/pacific-atlantic-water-flow/HC-kang.ts @@ -0,0 +1,115 @@ +/** + * https://leetcode.com/problems/pacific-atlantic-water-flow + * T.C. O((m * n)^2) + * S.C. O(m * n) + */ +function pacificAtlantic(heights: number[][]): number[][] { + const dir = [ + [0, 1], + [0, -1], + [1, 0], + [-1, 0], + ]; + + function pacificDfs(row: number, col: number, visited: Set) { + const key = `${row},${col}`; + if (visited.has(key)) return; + visited.add(key); + + if (row === 0 || col === 0) { + // left or top + return true; + } + + for (let [r, c] of dir) { + if (row + r < 0 || row + r >= heights.length) continue; + if (col + c < 0 || col + c >= heights[0].length) continue; + if (heights[row][col] < heights[row + r][col + c]) continue; + if (pacificDfs(row + r, col + c, visited)) return true; + } + return false; + } + + function atlanticDfs(row: number, col: number, visited: Set) { + const key = `${row},${col}`; + if (visited.has(key)) return; + visited.add(key); + + if (row === heights.length - 1 || col === heights[0].length - 1) { + // right or bottom + return true; + } + + for (let [r, c] of dir) { + if (row + r < 0 || row + r >= heights.length) continue; + if (col + c < 0 || col + c >= heights[0].length) continue; + if (heights[row][col] < heights[row + r][col + c]) continue; + if (atlanticDfs(row + r, col + c, visited)) return true; + } + return false; + } + + const result: number[][] = []; + for (let i = 0; i < heights.length; i++) { + for (let j = 0; j < heights[0].length; j++) { + if ( + pacificDfs(i, j, new Set()) && + atlanticDfs(i, j, new Set()) + ) { + result.push([i, j]); + } + } + } + + return result; +} + +/** + * T.C. O(m * n) + * S.C. O(m * n) + */ +function pacificAtlantic(heights: number[][]): number[][] { + const pacific: Set = new Set(); + const atlantic: Set = new Set(); + + const dir = [ + [0, 1], + [0, -1], + [1, 0], + [-1, 0], + ]; + + function dfs(row: number, col: number, visited: Set) { + const key = `${row},${col}`; + if (visited.has(key)) return; + visited.add(key); + + for (let [r, c] of dir) { + if (row + r < 0 || row + r >= heights.length) continue; + if (col + c < 0 || col + c >= heights[0].length) continue; + if (heights[row][col] > heights[row + r][col + c]) continue; + dfs(row + r, col + c, visited); + } + } + + for (let i = 0; i < heights.length; i++) { + dfs(i, 0, pacific); + dfs(i, heights[0].length - 1, atlantic); + } + + for (let i = 0; i < heights[0].length; i++) { + dfs(0, i, pacific); + dfs(heights.length - 1, i, atlantic); + } + + const result: number[][] = []; + + for (const p of pacific) { + if (atlantic.has(p)) { + const [row, col] = p.split(',').map(Number); + result.push([row, col]); + } + } + + return result; +}