From 73793cad7a5e5697c319de5ba5fefb38eb83dbe2 Mon Sep 17 00:00:00 2001 From: Libin YANG Date: Sat, 28 Dec 2024 17:44:44 +0800 Subject: [PATCH] feat: add solutions to lc problem: No.240 (#3898) No.0240.Search a 2D Matrix II --- .../0000-0099/0048.Rotate Image/README.md | 4 +- .../0000-0099/0048.Rotate Image/README_EN.md | 4 +- .../0240.Search a 2D Matrix II/README.md | 67 +++++++++-------- .../0240.Search a 2D Matrix II/README_EN.md | 73 +++++++++++-------- .../0240.Search a 2D Matrix II/Solution.js | 13 +--- .../0240.Search a 2D Matrix II/Solution.ts | 13 +--- .../0240.Search a 2D Matrix II/Solution2.rs | 22 ++++++ 7 files changed, 109 insertions(+), 87 deletions(-) create mode 100644 solution/0200-0299/0240.Search a 2D Matrix II/Solution2.rs diff --git a/solution/0000-0099/0048.Rotate Image/README.md b/solution/0000-0099/0048.Rotate Image/README.md index b9e91ba9da144..dd26439b6c5a3 100644 --- a/solution/0000-0099/0048.Rotate Image/README.md +++ b/solution/0000-0099/0048.Rotate Image/README.md @@ -58,9 +58,9 @@ tags: ### 方法一:原地翻转 -根据题目要求,我们实际上需要将 $matrix[i][j]$ 旋转至 $matrix[j][n - i - 1]$。 +根据题目要求,我们实际上需要将 $\text{matrix}[i][j]$ 旋转至 $\text{matrix}[j][n - i - 1]$。 -我们可以先对矩阵进行上下翻转,即 $matrix[i][j]$ 和 $matrix[n - i - 1][j]$ 进行交换,然后再对矩阵进行主对角线翻转,即 $matrix[i][j]$ 和 $matrix[j][i]$ 进行交换。这样就能将 $matrix[i][j]$ 旋转至 $matrix[j][n - i - 1]$ 了。 +我们可以先对矩阵进行上下翻转,即 $\text{matrix}[i][j]$ 和 $\text{matrix}[n - i - 1][j]$ 进行交换,然后再对矩阵进行主对角线翻转,即 $\text{matrix}[i][j]$ 和 $\text{matrix}[j][i]$ 进行交换。这样就能将 $\text{matrix}[i][j]$ 旋转至 $\text{matrix}[j][n - i - 1]$ 了。 时间复杂度 $O(n^2)$,其中 $n$ 是矩阵的边长。空间复杂度 $O(1)$。 diff --git a/solution/0000-0099/0048.Rotate Image/README_EN.md b/solution/0000-0099/0048.Rotate Image/README_EN.md index afa7215e405b8..567322e5ad238 100644 --- a/solution/0000-0099/0048.Rotate Image/README_EN.md +++ b/solution/0000-0099/0048.Rotate Image/README_EN.md @@ -54,9 +54,9 @@ tags: ### Solution 1: In-place Rotation -According to the problem requirements, we actually need to rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$. +According to the problem requirements, we need to rotate $\text{matrix}[i][j]$ to $\text{matrix}[j][n - i - 1]$. -We can first flip the matrix upside down, that is, swap $matrix[i][j]$ and $matrix[n - i - 1][j]$, and then flip the matrix along the main diagonal, that is, swap $matrix[i][j]$ and $matrix[j][i]$. This way, we can rotate $matrix[i][j]$ to $matrix[j][n - i - 1]$. +We can first flip the matrix upside down, i.e., swap $\text{matrix}[i][j]$ with $\text{matrix}[n - i - 1][j]$, and then flip the matrix along the main diagonal, i.e., swap $\text{matrix}[i][j]$ with $\text{matrix}[j][i]$. This way, we can rotate $\text{matrix}[i][j]$ to $\text{matrix}[j][n - i - 1]$. The time complexity is $O(n^2)$, where $n$ is the side length of the matrix. The space complexity is $O(1)$. diff --git a/solution/0200-0299/0240.Search a 2D Matrix II/README.md b/solution/0200-0299/0240.Search a 2D Matrix II/README.md index 70b13fc1bb898..bdbf7ecbcac7b 100644 --- a/solution/0200-0299/0240.Search a 2D Matrix II/README.md +++ b/solution/0200-0299/0240.Search a 2D Matrix II/README.md @@ -64,9 +64,9 @@ tags: ### 方法一:二分查找 -由于每一行的所有元素升序排列,因此,对于每一行,我们可以使用二分查找找到第一个大于等于 `target` 的元素,然后判断该元素是否等于 `target`。如果等于 `target`,说明找到了目标值,直接返回 `true`。如果不等于 `target`,说明这一行的所有元素都小于 `target`,应该继续搜索下一行。 +由于每一行的所有元素升序排列,因此,对于每一行,我们可以使用二分查找找到第一个大于等于 $\textit{target}$ 的元素,然后判断该元素是否等于 $\textit{target}$。如果等于 $\textit{target}$,说明找到了目标值,直接返回 $\text{true}$。如果不等于 $\textit{target}$,说明这一行的所有元素都小于 $\textit{target}$,应该继续搜索下一行。 -如果所有行都搜索完了,都没有找到目标值,说明目标值不存在,返回 `false`。 +如果所有行都搜索完了,都没有找到目标值,说明目标值不存在,返回 $\text{false}$。 时间复杂度 $O(m \times \log n)$,其中 $m$ 和 $n$ 分别为矩阵的行数和列数。空间复杂度 $O(1)$。 @@ -137,17 +137,8 @@ func searchMatrix(matrix [][]int, target int) bool { function searchMatrix(matrix: number[][], target: number): boolean { const n = matrix[0].length; for (const row of matrix) { - let left = 0, - right = n; - while (left < right) { - const mid = (left + right) >> 1; - if (row[mid] >= target) { - right = mid; - } else { - left = mid + 1; - } - } - if (left != n && row[left] == target) { + const j = _.sortedIndex(row, target); + if (j < n && row[j] === target) { return true; } } @@ -195,17 +186,8 @@ impl Solution { var searchMatrix = function (matrix, target) { const n = matrix[0].length; for (const row of matrix) { - let left = 0, - right = n; - while (left < right) { - const mid = (left + right) >> 1; - if (row[mid] >= target) { - right = mid; - } else { - left = mid + 1; - } - } - if (left != n && row[left] == target) { + const j = _.sortedIndex(row, target); + if (j < n && row[j] == target) { return true; } } @@ -237,13 +219,13 @@ public class Solution { ### 方法二:从左下角或右上角搜索 -这里我们以左下角作为起始搜索点,往右上方向开始搜索,比较当前元素 `matrix[i][j]`与 `target` 的大小关系: +这里我们以左下角或右上角作为起始搜索点,往右上或左下方向开始搜索。比较当前元素 $\textit{matrix}[i][j]$ 与 $\textit{target}$ 的大小关系: -- 若 $\textit{matrix}[i][j] = \textit{target}$,说明找到了目标值,直接返回 `true`。 -- 若 $\textit{matrix}[i][j] > \textit{target}$,说明这一列从当前位置开始往上的所有元素均大于 `target`,应该让 $i$ 指针往上移动,即 $i \leftarrow i - 1$。 -- 若 $\textit{matrix}[i][j] < \textit{target}$,说明这一行从当前位置开始往右的所有元素均小于 `target`,应该让 $j$ 指针往右移动,即 $j \leftarrow j + 1$。 +- 若 $\textit{matrix}[i][j] = \textit{target}$,说明找到了目标值,直接返回 $\text{true}$。 +- 若 $\textit{matrix}[i][j] > \textit{target}$,说明这一列从当前位置开始往上的所有元素均大于 $\textit{target}$,应该让 $i$ 指针往上移动,即 $i \leftarrow i - 1$。 +- 若 $\textit{matrix}[i][j] < \textit{target}$,说明这一行从当前位置开始往右的所有元素均小于 $\textit{target}$,应该让 $j$ 指针往右移动,即 $j \leftarrow j + 1$。 -若搜索结束依然找不到 `target`,返回 `false`。 +若搜索结束依然找不到 $\textit{target}$,返回 $\text{false}$。 时间复杂度 $O(m + n)$,其中 $m$ 和 $n$ 分别为矩阵的行数和列数。空间复杂度 $O(1)$。 @@ -351,6 +333,33 @@ function searchMatrix(matrix: number[][], target: number): boolean { } ``` +#### Rust + +```rust +impl Solution { + pub fn search_matrix(matrix: Vec>, target: i32) -> bool { + let m = matrix.len(); + let n = matrix[0].len(); + let mut i = m - 1; + let mut j = 0; + while i >= 0 && j < n { + if matrix[i][j] == target { + return true; + } + if matrix[i][j] > target { + if i == 0 { + break; + } + i -= 1; + } else { + j += 1; + } + } + false + } +} +``` + #### C# ```cs diff --git a/solution/0200-0299/0240.Search a 2D Matrix II/README_EN.md b/solution/0200-0299/0240.Search a 2D Matrix II/README_EN.md index 2c2559f1266e7..673e6bd295c2c 100644 --- a/solution/0200-0299/0240.Search a 2D Matrix II/README_EN.md +++ b/solution/0200-0299/0240.Search a 2D Matrix II/README_EN.md @@ -62,11 +62,11 @@ tags: ### Solution 1: Binary Search -Since all elements in each row are sorted in ascending order, we can use binary search to find the first element that is greater than or equal to `target` for each row, and then check if this element is equal to `target`. If it equals `target`, it means the target value has been found, and we directly return `true`. If it does not equal `target`, it means all elements in this row are less than `target`, and we should continue to search the next row. +Since all elements in each row are sorted in ascending order, for each row, we can use binary search to find the first element greater than or equal to $\textit{target}$, and then check if that element is equal to $\textit{target}$. If it is equal to $\textit{target}$, it means the target value is found, and we return $\text{true}$. If it is not equal to $\textit{target}$, it means all elements in this row are less than $\textit{target}$, and we should continue searching the next row. -If all rows have been searched and the target value has not been found, it means the target value does not exist, so we return `false`. +If all rows have been searched and the target value is not found, it means the target value does not exist, and we return $\text{false}$. -The time complexity is $O(m \times \log n)$, where $m$ and $n$ are the number of rows and columns in the matrix, respectively. The space complexity is $O(1)$. +The time complexity is $O(m \times \log n)$, where $m$ and $n$ are the number of rows and columns of the matrix, respectively. The space complexity is $O(1)$. @@ -135,17 +135,8 @@ func searchMatrix(matrix [][]int, target int) bool { function searchMatrix(matrix: number[][], target: number): boolean { const n = matrix[0].length; for (const row of matrix) { - let left = 0, - right = n; - while (left < right) { - const mid = (left + right) >> 1; - if (row[mid] >= target) { - right = mid; - } else { - left = mid + 1; - } - } - if (left != n && row[left] == target) { + const j = _.sortedIndex(row, target); + if (j < n && row[j] === target) { return true; } } @@ -193,17 +184,8 @@ impl Solution { var searchMatrix = function (matrix, target) { const n = matrix[0].length; for (const row of matrix) { - let left = 0, - right = n; - while (left < right) { - const mid = (left + right) >> 1; - if (row[mid] >= target) { - right = mid; - } else { - left = mid + 1; - } - } - if (left != n && row[left] == target) { + const j = _.sortedIndex(row, target); + if (j < n && row[j] == target) { return true; } } @@ -233,17 +215,17 @@ public class Solution { -### Solution 2: Search from the Bottom Left or Top Right +### Solution 2: Search from Bottom-Left or Top-Right -Here, we start searching from the bottom left corner and move towards the top right direction, comparing the current element `matrix[i][j]` with `target`: +We start the search from the bottom-left or top-right corner and move towards the top-right or bottom-left direction. Compare the current element $\textit{matrix}[i][j]$ with $\textit{target}$: -- If $\textit{matrix}[i][j] = \textit{target}$, it means the target value has been found, and we directly return `true`. -- If $\textit{matrix}[i][j] > \textit{target}$, it means all elements in this column from the current position upwards are greater than `target`, so we should move the $i$ pointer upwards, i.e., $i \leftarrow i - 1$. -- If $\textit{matrix}[i][j] < \textit{target}$, it means all elements in this row from the current position to the right are less than `target`, so we should move the $j$ pointer to the right, i.e., $j \leftarrow j + 1$. +- If $\textit{matrix}[i][j] = \textit{target}$, it means the target value is found, and we return $\text{true}$. +- If $\textit{matrix}[i][j] > \textit{target}$, it means all elements in this column from the current position upwards are greater than $\textit{target}$, so we move the $i$ pointer upwards, i.e., $i \leftarrow i - 1$. +- If $\textit{matrix}[i][j] < \textit{target}$, it means all elements in this row from the current position to the right are less than $\textit{target}$, so we move the $j$ pointer to the right, i.e., $j \leftarrow j + 1$. -If the search ends and the `target` is still not found, return `false`. +If the search ends and the $\textit{target}$ is not found, return $\text{false}$. -The time complexity is $O(m + n)$, where $m$ and $n$ are the number of rows and columns in the matrix, respectively. The space complexity is $O(1)$. +The time complexity is $O(m + n)$, where $m$ and $n$ are the number of rows and columns of the matrix, respectively. The space complexity is $O(1)$. @@ -349,6 +331,33 @@ function searchMatrix(matrix: number[][], target: number): boolean { } ``` +#### Rust + +```rust +impl Solution { + pub fn search_matrix(matrix: Vec>, target: i32) -> bool { + let m = matrix.len(); + let n = matrix[0].len(); + let mut i = m - 1; + let mut j = 0; + while i >= 0 && j < n { + if matrix[i][j] == target { + return true; + } + if matrix[i][j] > target { + if i == 0 { + break; + } + i -= 1; + } else { + j += 1; + } + } + false + } +} +``` + #### C# ```cs diff --git a/solution/0200-0299/0240.Search a 2D Matrix II/Solution.js b/solution/0200-0299/0240.Search a 2D Matrix II/Solution.js index 9b0bec1b57241..1f77e0c461483 100644 --- a/solution/0200-0299/0240.Search a 2D Matrix II/Solution.js +++ b/solution/0200-0299/0240.Search a 2D Matrix II/Solution.js @@ -6,17 +6,8 @@ var searchMatrix = function (matrix, target) { const n = matrix[0].length; for (const row of matrix) { - let left = 0, - right = n; - while (left < right) { - const mid = (left + right) >> 1; - if (row[mid] >= target) { - right = mid; - } else { - left = mid + 1; - } - } - if (left != n && row[left] == target) { + const j = _.sortedIndex(row, target); + if (j < n && row[j] == target) { return true; } } diff --git a/solution/0200-0299/0240.Search a 2D Matrix II/Solution.ts b/solution/0200-0299/0240.Search a 2D Matrix II/Solution.ts index bf1cea5bb060b..bd9a915aae285 100644 --- a/solution/0200-0299/0240.Search a 2D Matrix II/Solution.ts +++ b/solution/0200-0299/0240.Search a 2D Matrix II/Solution.ts @@ -1,17 +1,8 @@ function searchMatrix(matrix: number[][], target: number): boolean { const n = matrix[0].length; for (const row of matrix) { - let left = 0, - right = n; - while (left < right) { - const mid = (left + right) >> 1; - if (row[mid] >= target) { - right = mid; - } else { - left = mid + 1; - } - } - if (left != n && row[left] == target) { + const j = _.sortedIndex(row, target); + if (j < n && row[j] === target) { return true; } } diff --git a/solution/0200-0299/0240.Search a 2D Matrix II/Solution2.rs b/solution/0200-0299/0240.Search a 2D Matrix II/Solution2.rs new file mode 100644 index 0000000000000..1ce784e3e4e19 --- /dev/null +++ b/solution/0200-0299/0240.Search a 2D Matrix II/Solution2.rs @@ -0,0 +1,22 @@ +impl Solution { + pub fn search_matrix(matrix: Vec>, target: i32) -> bool { + let m = matrix.len(); + let n = matrix[0].len(); + let mut i = m - 1; + let mut j = 0; + while i >= 0 && j < n { + if matrix[i][j] == target { + return true; + } + if matrix[i][j] > target { + if i == 0 { + break; + } + i -= 1; + } else { + j += 1; + } + } + false + } +}