Skip to content

Commit

Permalink
feat: add solutions to lc problem: No.240 (#3898)
Browse files Browse the repository at this point in the history
No.0240.Search a 2D Matrix II
  • Loading branch information
yanglbme authored Dec 28, 2024
1 parent 988caec commit 73793ca
Show file tree
Hide file tree
Showing 7 changed files with 109 additions and 87 deletions.
4 changes: 2 additions & 2 deletions solution/0000-0099/0048.Rotate Image/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)$。

Expand Down
4 changes: 2 additions & 2 deletions solution/0000-0099/0048.Rotate Image/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)$.

Expand Down
67 changes: 38 additions & 29 deletions solution/0200-0299/0240.Search a 2D Matrix II/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)$。

Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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)$。

Expand Down Expand Up @@ -351,6 +333,33 @@ function searchMatrix(matrix: number[][], target: number): boolean {
}
```

#### Rust

```rust
impl Solution {
pub fn search_matrix(matrix: Vec<Vec<i32>>, 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
Expand Down
73 changes: 41 additions & 32 deletions solution/0200-0299/0240.Search a 2D Matrix II/README_EN.md
Original file line number Diff line number Diff line change
Expand Up @@ -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)$.

<!-- tabs:start -->

Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -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;
}
}
Expand Down Expand Up @@ -233,17 +215,17 @@ public class Solution {

<!-- solution:start -->

### 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)$.

<!-- tabs:start -->

Expand Down Expand Up @@ -349,6 +331,33 @@ function searchMatrix(matrix: number[][], target: number): boolean {
}
```

#### Rust

```rust
impl Solution {
pub fn search_matrix(matrix: Vec<Vec<i32>>, 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
Expand Down
13 changes: 2 additions & 11 deletions solution/0200-0299/0240.Search a 2D Matrix II/Solution.js
Original file line number Diff line number Diff line change
Expand Up @@ -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;
}
}
Expand Down
13 changes: 2 additions & 11 deletions solution/0200-0299/0240.Search a 2D Matrix II/Solution.ts
Original file line number Diff line number Diff line change
@@ -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;
}
}
Expand Down
22 changes: 22 additions & 0 deletions solution/0200-0299/0240.Search a 2D Matrix II/Solution2.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
impl Solution {
pub fn search_matrix(matrix: Vec<Vec<i32>>, 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
}
}

0 comments on commit 73793ca

Please sign in to comment.