diff --git a/longest-substring-without-repeating-characters/Jeehay28.ts b/longest-substring-without-repeating-characters/Jeehay28.ts new file mode 100644 index 000000000..6817f3a0e --- /dev/null +++ b/longest-substring-without-repeating-characters/Jeehay28.ts @@ -0,0 +1,21 @@ +// TC: O(n) +// SC: O(n) + +function lengthOfLongestSubstring(s: string): number { + let seen = new Map(); + let maxLength = 0; + let start = 0; + + for (let end = 0; end < s.length; end++) { + const ch = s[end]; + + if (seen.has(ch) && seen.get(ch)! >= start) { + start = seen.get(ch)! + 1; + } + + seen.set(ch, end); + maxLength = Math.max(maxLength, end - start + 1); + } + + return maxLength; +} diff --git a/number-of-islands/Jeehay28.ts b/number-of-islands/Jeehay28.ts new file mode 100644 index 000000000..f4114ee2a --- /dev/null +++ b/number-of-islands/Jeehay28.ts @@ -0,0 +1,41 @@ +// TC: O(n), where N = total number of cells = m * n +// SC: O(n) + +function numIslands(grid: string[][]): number { + const sink = (row: number, col: number) => { + visited[row][col] = true; + + const dirs = [ + [row - 1, col], + [row + 1, col], + [row, col - 1], + [row, col + 1], + ]; + + for (const dir of dirs) { + const [r, c] = dir; + + if (r >= 0 && r < grid.length && c >= 0 && c < grid[0].length) { + if (!visited[r][c] && grid[r][c] === "1") { + sink(r, c); + } + } + } + }; + + let count = 0; + const visited: boolean[][] = Array.from({ length: grid.length }, () => + Array(grid[0].length).fill(false) + ); + + for (let i = 0; i < grid.length; i++) { + for (let j = 0; j < grid[0].length; j++) { + if (!visited[i][j] && grid[i][j] === "1") { + count++; + sink(i, j); // // Sink all connected neighboring land cells + } + } + } + + return count; +} diff --git a/reverse-linked-list/Jeehay28.ts b/reverse-linked-list/Jeehay28.ts new file mode 100644 index 000000000..199cb5307 --- /dev/null +++ b/reverse-linked-list/Jeehay28.ts @@ -0,0 +1,34 @@ +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; + } +} + +// TC: O(n) +// SC: O(1) +function reverseList(head: ListNode | null): ListNode | null { + if (!head) return head; + + // 1 -> 2 -> 3 -> 4 -> 5 -> null + + // null <- 1 + // prev curr + + // null <- 1 <- 2 + // prev cur + + let prev: ListNode | null = null; + let curr: ListNode | null = head; + + while (curr) { + const tempNext: ListNode | null = curr.next; // 2 -> 3 -> 4 -> 5 -> null + curr.next = prev; // curr: 1 -> null + prev = curr; // curr: 1 -> null, 2 -> 1 -> null + curr = tempNext; + } + + return prev; +} diff --git a/set-matrix-zeroes/Jeehay28.ts b/set-matrix-zeroes/Jeehay28.ts new file mode 100644 index 000000000..1e303a9ce --- /dev/null +++ b/set-matrix-zeroes/Jeehay28.ts @@ -0,0 +1,95 @@ +/** + Do not return anything, modify matrix in-place instead. + */ + +// TC: O(m * n) +// ✅ SC: O(1) +function setZeroes(matrix: number[][]): void { + let isFirstRowZero: boolean = false; + let isFirstColZero: boolean = false; + + // check if the first row has any zeros + for (let col = 0; col < matrix[0].length; col++) { + if (matrix[0][col] === 0) { + isFirstRowZero = true; + break; + } + } + + // check if the first column has any zeros + for (let row = 0; row < matrix.length; row++) { + if (matrix[row][0] === 0) { + isFirstColZero = true; + break; + } + } + + // Use the first row and column to mark rows and columns that need to be zeroed + for (let row = 1; row < matrix.length; row++) { + for (let col = 1; col < matrix[0].length; col++) { + if (matrix[row][col] === 0) { + matrix[row][0] = 0; + matrix[0][col] = 0; + } + } + } + + // Set matrix cells to zero based on markers in the first row and column + for (let row = 1; row < matrix.length; row++) { + for (let col = 1; col < matrix[0].length; col++) { + if (matrix[row][0] === 0 || matrix[0][col] === 0) { + matrix[row][col] = 0; + } + } + } + + // Zero out the first row if needed + if (isFirstRowZero) { + for (let col = 0; col < matrix[0].length; col++) { + matrix[0][col] = 0; + } + } + + // Zero out the first column if needed + if (isFirstColZero) { + for (let row = 0; row < matrix.length; row++) { + matrix[row][0] = 0; + } + } +} + + +// TC: O(m * n) +// SC: O(m + n) +/* +function setZeroes(matrix: number[][]): void { + + const rows = new Set(); + const cols = new Set(); + + // Identify all rows and columns that contain at least one zero + for (let row = 0; row < matrix.length; row++) { + for (let col = 0; col < matrix[0].length; col++) { + if (matrix[row][col] === 0) { + rows.add(row); + cols.add(col); + } + } + } + + // Set all elements in the identified rows to zero + for (const row of rows) { + for (let col = 0; col < matrix[0].length; col++) { + matrix[row][col] = 0; + } + } + + // Set all elements in the identified columns to zero + for (const col of cols) { + for (let row = 0; row < matrix.length; row++) { + matrix[row][col] = 0; + } + } +}; +*/ + diff --git a/unique-paths/Jeehay28.ts b/unique-paths/Jeehay28.ts new file mode 100644 index 000000000..57d0fb6ab --- /dev/null +++ b/unique-paths/Jeehay28.ts @@ -0,0 +1,41 @@ +// Memoized DFS +// TC: O(m * n) +// SC: O(m * n) +function uniquePaths(m: number, n: number): number { + const memo = new Map(); + + const traverse = (row: number, col: number) => { + if (row >= m || col >= n) return 0; + if (row === m - 1 && col === n - 1) return 1; + const key = `${row}-${col}`; + if (memo.has(key)) return memo.get(key); + + const result = traverse(row + 1, col) + traverse(row, col + 1); + memo.set(key, result); + return result; + }; + + return traverse(0, 0); +} + +// DP +// TC: O(m * n) +// SC: O(m * n) +/* +function uniquePaths(m: number, n: number): number { + + // 1, 1, 1 + // 1, 1+1=2, 1+(1+1)=3 + + const dp = Array.from({length: m}, () => Array(n).fill(1)); + + for(let i=1; i