diff --git a/README.md b/README.md index 2c6669c..8445602 100644 --- a/README.md +++ b/README.md @@ -996,6 +996,7 @@ TypeScript-based LeetCode algorithm problem solutions, regularly updated. | | | | | | |-|-|-|-|-|- | 0200 |[Number of Islands](src/main/ts/g0101_0200/s0200_number_of_islands/solution.ts)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Array, Depth_First_Search, Breadth_First_Search, Matrix, Union_Find, Big_O_Time_O(M\*N)_Space_O(M\*N) | 57 | 93.94 +| 0133 |[Clone Graph](src/main/ts/g0101_0200/s0133_clone_graph/solution.ts)| Medium | Hash_Table, Depth_First_Search, Breadth_First_Search, Graph | 48 | 82.94 #### Udemy Dynamic Programming @@ -1186,6 +1187,8 @@ TypeScript-based LeetCode algorithm problem solutions, regularly updated. | | | | | | |-|-|-|-|-|- | 0200 |[Number of Islands](src/main/ts/g0101_0200/s0200_number_of_islands/solution.ts)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Array, Depth_First_Search, Breadth_First_Search, Matrix, Union_Find, Big_O_Time_O(M\*N)_Space_O(M\*N) | 57 | 93.94 +| 0130 |[Surrounded Regions](src/main/ts/g0101_0200/s0130_surrounded_regions/solution.ts)| Medium | Top_Interview_Questions, Array, Depth_First_Search, Breadth_First_Search, Matrix, Union_Find | 1 | 99.18 +| 0133 |[Clone Graph](src/main/ts/g0101_0200/s0133_clone_graph/solution.ts)| Medium | Hash_Table, Depth_First_Search, Breadth_First_Search, Graph | 48 | 82.94 | 0399 |[Evaluate Division](src/main/ts/g0301_0400/s0399_evaluate_division/solution.ts)| Medium | Array, Depth_First_Search, Breadth_First_Search, Graph, Union_Find, Shortest_Path | 0 | 100.00 | 0207 |[Course Schedule](src/main/ts/g0201_0300/s0207_course_schedule/solution.ts)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Depth_First_Search, Breadth_First_Search, Graph, Topological_Sort, Big_O_Time_O(N)_Space_O(N) | 11 | 81.08 | 0210 |[Course Schedule II](src/main/ts/g0201_0300/s0210_course_schedule_ii/solution.ts)| Medium | Top_Interview_Questions, Depth_First_Search, Breadth_First_Search, Graph, Topological_Sort | 2 | 99.76 @@ -1669,6 +1672,7 @@ TypeScript-based LeetCode algorithm problem solutions, regularly updated. | | | | | | |-|-|-|-|-|- +| 0130 |[Surrounded Regions](src/main/ts/g0101_0200/s0130_surrounded_regions/solution.ts)| Medium | Top_Interview_Questions, Array, Depth_First_Search, Breadth_First_Search, Matrix, Union_Find | 1 | 99.18 #### Day 9 Recursion Backtracking @@ -1843,7 +1847,9 @@ TypeScript-based LeetCode algorithm problem solutions, regularly updated. | 0136 |[Single Number](src/main/ts/g0101_0200/s0136_single_number/solution.ts)| Easy | Top_100_Liked_Questions, Top_Interview_Questions, Array, Bit_Manipulation, Data_Structure_II_Day_1_Array, Algorithm_I_Day_14_Bit_Manipulation, Udemy_Integers, Top_Interview_150_Bit_Manipulation, Big_O_Time_O(N)_Space_O(1) | 1 | 78.27 | 0135 |[Candy](src/main/ts/g0101_0200/s0135_candy/solution.ts)| Hard | Array, Greedy, Top_Interview_150_Array/String | 2 | 96.15 | 0134 |[Gas Station](src/main/ts/g0101_0200/s0134_gas_station/solution.ts)| Medium | Top_Interview_Questions, Array, Greedy, Top_Interview_150_Array/String | 0 | 100.00 +| 0133 |[Clone Graph](src/main/ts/g0101_0200/s0133_clone_graph/solution.ts)| Medium | Hash_Table, Depth_First_Search, Breadth_First_Search, Graph, Udemy_Graph, Top_Interview_150_Graph_General | 48 | 82.94 | 0131 |[Palindrome Partitioning](src/main/ts/g0101_0200/s0131_palindrome_partitioning/solution.ts)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, String, Dynamic_Programming, Backtracking, Big_O_Time_O(N\*2^N)_Space_O(2^N\*N) | 13 | 94.96 +| 0130 |[Surrounded Regions](src/main/ts/g0101_0200/s0130_surrounded_regions/solution.ts)| Medium | Top_Interview_Questions, Array, Depth_First_Search, Breadth_First_Search, Matrix, Union_Find, Algorithm_II_Day_8_Breadth_First_Search_Depth_First_Search, Top_Interview_150_Graph_General | 1 | 99.18 | 0129 |[Sum Root to Leaf Numbers](src/main/ts/g0101_0200/s0129_sum_root_to_leaf_numbers/solution.ts)| Medium | Depth_First_Search, Tree, Binary_Tree, Top_Interview_150_Binary_Tree_General | 0 | 100.00 | 0128 |[Longest Consecutive Sequence](src/main/ts/g0101_0200/s0128_longest_consecutive_sequence/solution.ts)| Medium | Top_100_Liked_Questions, Top_Interview_Questions, Array, Hash_Table, Union_Find, Top_Interview_150_Hashmap, Big_O_Time_O(N_log_N)_Space_O(1) | 34 | 90.07 | 0127 |[Word Ladder](src/main/ts/g0101_0200/s0127_word_ladder/solution.ts)| Hard | Top_Interview_Questions, String, Hash_Table, Breadth_First_Search, Graph_Theory_I_Day_12_Breadth_First_Search, Top_Interview_150_Graph_BFS | 41 | 95.63 diff --git a/src/main/ts/g0101_0200/s0130_surrounded_regions/readme.md b/src/main/ts/g0101_0200/s0130_surrounded_regions/readme.md new file mode 100644 index 0000000..6b12aaa --- /dev/null +++ b/src/main/ts/g0101_0200/s0130_surrounded_regions/readme.md @@ -0,0 +1,30 @@ +130\. Surrounded Regions + +Medium + +Given an `m x n` matrix `board` containing `'X'` and `'O'`, _capture all regions that are 4-directionally surrounded by_ `'X'`. + +A region is **captured** by flipping all `'O'`s into `'X'`s in that surrounded region. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2021/02/19/xogrid.jpg) + +**Input:** board = [["X","X","X","X"],["X","O","O","X"],["X","X","O","X"],["X","O","X","X"]] + +**Output:** [["X","X","X","X"],["X","X","X","X"],["X","X","X","X"],["X","O","X","X"]] + +**Explanation:** Surrounded regions should not be on the border, which means that any 'O' on the border of the board are not flipped to 'X'. Any 'O' that is not on the border and it is not connected to an 'O' on the border will be flipped to 'X'. Two cells are connected if they are adjacent cells connected horizontally or vertically. + +**Example 2:** + +**Input:** board = [["X"]] + +**Output:** [["X"]] + +**Constraints:** + +* `m == board.length` +* `n == board[i].length` +* `1 <= m, n <= 200` +* `board[i][j]` is `'X'` or `'O'`. \ No newline at end of file diff --git a/src/main/ts/g0101_0200/s0130_surrounded_regions/solution.ts b/src/main/ts/g0101_0200/s0130_surrounded_regions/solution.ts new file mode 100644 index 0000000..db3fb81 --- /dev/null +++ b/src/main/ts/g0101_0200/s0130_surrounded_regions/solution.ts @@ -0,0 +1,52 @@ +// #Medium #Top_Interview_Questions #Array #Depth_First_Search #Breadth_First_Search #Matrix +// #Union_Find #Algorithm_II_Day_8_Breadth_First_Search_Depth_First_Search +// #Top_Interview_150_Graph_General #2025_04_16_Time_1_ms_(99.18%)_Space_59.64_MB_(82.97%) + +/** + Do not return anything, modify board in-place instead. + */ +function solve(board: string[][]): void { + if (board.length === 0) { + return + } + const rows = board.length + const cols = board[0].length + const dfs = (board: string[][], row: number, col: number): void => { + if (row < 0 || row >= rows || col < 0 || col >= cols || board[row][col] !== 'O') { + return + } + board[row][col] = '#' + dfs(board, row + 1, col) + dfs(board, row - 1, col) + dfs(board, row, col + 1) + dfs(board, row, col - 1) + } + for (let i = 0; i < cols; i++) { + if (board[0][i] === 'O') { + dfs(board, 0, i) + } + if (board[rows - 1][i] === 'O') { + dfs(board, rows - 1, i) + } + } + for (let i = 0; i < rows; i++) { + if (board[i][0] === 'O') { + dfs(board, i, 0) + } + if (board[i][cols - 1] === 'O') { + dfs(board, i, cols - 1) + } + } + for (let i = 0; i < rows; i++) { + for (let j = 0; j < cols; j++) { + if (board[i][j] === 'O') { + board[i][j] = 'X' + } + if (board[i][j] === '#') { + board[i][j] = 'O' + } + } + } +} + +export { solve } diff --git a/src/main/ts/g0101_0200/s0133_clone_graph/readme.md b/src/main/ts/g0101_0200/s0133_clone_graph/readme.md new file mode 100644 index 0000000..97ec332 --- /dev/null +++ b/src/main/ts/g0101_0200/s0133_clone_graph/readme.md @@ -0,0 +1,69 @@ +133\. Clone Graph + +Medium + +Given a reference of a node in a **[connected](https://en.wikipedia.org/wiki/Connectivity_(graph_theory)#Connected_graph)** undirected graph. + +Return a [**deep copy**](https://en.wikipedia.org/wiki/Object_copying#Deep_copy) (clone) of the graph. + +Each node in the graph contains a value (`int`) and a list (`List[Node]`) of its neighbors. + +class Node { public int val; public List neighbors; } + +**Test case format:** + +For simplicity, each node's value is the same as the node's index (1-indexed). For example, the first node with `val == 1`, the second node with `val == 2`, and so on. The graph is represented in the test case using an adjacency list. + +**An adjacency list** is a collection of unordered **lists** used to represent a finite graph. Each list describes the set of neighbors of a node in the graph. + +The given node will always be the first node with `val = 1`. You must return the **copy of the given node** as a reference to the cloned graph. + +**Example 1:** + +![](https://assets.leetcode.com/uploads/2019/11/04/133_clone_graph_question.png) + +**Input:** adjList = [[2,4],[1,3],[2,4],[1,3]] + +**Output:** [[2,4],[1,3],[2,4],[1,3]] + +**Explanation:** + + There are 4 nodes in the graph. + 1st node (val = 1)'s neighbors are 2nd node (val = 2) and 4th node (val = 4). + 2nd node (val = 2)'s neighbors are 1st node (val = 1) and 3rd node (val = 3). + 3rd node (val = 3)'s neighbors are 2nd node (val = 2) and 4th node (val = 4). + 4th node (val = 4)'s neighbors are 1st node (val = 1) and 3rd node (val = 3). + +**Example 2:** + +![](https://assets.leetcode.com/uploads/2020/01/07/graph.png) + +**Input:** adjList = [[]] + +**Output:** [[]] + +**Explanation:** Note that the input contains one empty list. The graph consists of only one node with val = 1 and it does not have any neighbors. + +**Example 3:** + +**Input:** adjList = [] + +**Output:** [] + +**Explanation:** This an empty graph, it does not have any nodes. + +**Example 4:** + +![](https://assets.leetcode.com/uploads/2020/01/07/graph-1.png) + +**Input:** adjList = [[2],[1]] + +**Output:** [[2],[1]] + +**Constraints:** + +* The number of nodes in the graph is in the range `[0, 100]`. +* `1 <= Node.val <= 100` +* `Node.val` is unique for each node. +* There are no repeated edges and no self-loops in the graph. +* The Graph is connected and all nodes can be visited starting from the given node. \ No newline at end of file diff --git a/src/main/ts/g0101_0200/s0133_clone_graph/solution.ts b/src/main/ts/g0101_0200/s0133_clone_graph/solution.ts new file mode 100644 index 0000000..171143e --- /dev/null +++ b/src/main/ts/g0101_0200/s0133_clone_graph/solution.ts @@ -0,0 +1,53 @@ +// #Medium #Hash_Table #Depth_First_Search #Breadth_First_Search #Graph #Udemy_Graph +// #Top_Interview_150_Graph_General #2025_04_16_Time_48_ms_(82.94%)_Space_58.20_MB_(70.18%) + +class Node { + val: number + neighbors: Node[] + + constructor(val: number = 0, neighbors: Node[] = []) { + this.val = val + this.neighbors = neighbors + } + + toString(): string { + const result: string[] = [] + for (const node of this.neighbors) { + if (node.neighbors.length === 0) { + result.push(node.val.toString()) + } else { + const result2: string[] = [] + for (const nodeItem of node.neighbors) { + result2.push(nodeItem.val.toString()) + } + result.push(`[${result2.join(',')}]`) + } + } + return `[${result.join(',')}]` + } +} + +function cloneGraph(node: Node | null): Node | null { + const processedNodes = new Map() + return cloneGraphHelper(node, processedNodes) +} + +function cloneGraphHelper(node: Node | null, processedNodes: Map): Node | null { + if (node === null) { + return null + } + if (processedNodes.has(node)) { + return processedNodes.get(node)! + } + const newNode = new Node(node.val) + processedNodes.set(node, newNode) + for (const neighbor of node.neighbors) { + const clonedNeighbor = cloneGraphHelper(neighbor, processedNodes) + if (clonedNeighbor !== null) { + newNode.neighbors.push(clonedNeighbor) + } + } + return newNode +} + +export { Node, cloneGraph } diff --git a/src/test/ts/g0101_0200/s0130_surrounded_regions/solution.test.ts b/src/test/ts/g0101_0200/s0130_surrounded_regions/solution.test.ts new file mode 100644 index 0000000..13ec8cd --- /dev/null +++ b/src/test/ts/g0101_0200/s0130_surrounded_regions/solution.test.ts @@ -0,0 +1,25 @@ +// tslint:disable:no-magic-numbers +import { solve } from 'src/main/ts/g0101_0200/s0130_surrounded_regions/solution' +import { expect, test } from 'vitest' + +test('solve', () => { + const board: string[][] = [ + ['X', 'X', 'X', 'X'], + ['X', 'O', 'O', 'X'], + ['X', 'X', 'O', 'X'], + ['X', 'O', 'X', 'X'], + ] + solve(board) + expect(board).toEqual([ + ['X', 'X', 'X', 'X'], + ['X', 'X', 'X', 'X'], + ['X', 'X', 'X', 'X'], + ['X', 'O', 'X', 'X'], + ]) +}) + +test('solve', () => { + const board: string[][] = [['X']] + solve(board) + expect(board).toEqual([['X']]) +}) diff --git a/src/test/ts/g0101_0200/s0133_clone_graph/solution.test.ts b/src/test/ts/g0101_0200/s0133_clone_graph/solution.test.ts new file mode 100644 index 0000000..1fd2f9d --- /dev/null +++ b/src/test/ts/g0101_0200/s0133_clone_graph/solution.test.ts @@ -0,0 +1,22 @@ +// tslint:disable:no-magic-numbers +import { Node, cloneGraph } from 'src/main/ts/g0101_0200/s0133_clone_graph/solution' +import { expect, test } from 'vitest' + +test('cloneGraph', () => { + const node1 = new Node(1) + const node2 = new Node(2) + const node3 = new Node(3) + const node4 = new Node(4) + node1.neighbors = [node2, node4] + node2.neighbors = [node1, node3] + node3.neighbors = [node2, node4] + node4.neighbors = [node1, node3] + const clonedNode1 = cloneGraph(node1) + expect(clonedNode1?.toString()).toEqual('[[1,3],[1,3]]') +}) + +test('cloneGraph2', () => { + const node1 = new Node(1) + const clonedNode1 = cloneGraph(node1) + expect(clonedNode1?.toString()).toEqual('[]') +})