Skip to content

Commit d34338b

Browse files
committed
feat: add solutions for lc No.1728
1 parent 918e254 commit d34338b

6 files changed

Lines changed: 855 additions & 10 deletions

File tree

solution/1700-1799/1727.Largest Submatrix With Rearrangements/README.md

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -84,13 +84,13 @@ tags:
8484

8585
由于题目中矩阵是按列进行重排,因此,我们可以先对矩阵的每一列进行预处理。
8686

87-
对于每个值为 $1$ 的元素,我们更新其值为该元素向上的最大连续的 $1$ 的个数,即 $matrix[i][j]=matrix[i-1][j]+1$。
87+
对于每个值为 $1$ 的元素,我们更新其值为该元素向上的最大连续的 $1$ 的个数,即 $\text{matrix}[i][j]=\text{matrix}[i-1][j]+1$。
8888

8989
接下来,我们可以对更新后的矩阵的每一行进行排序。然后遍历每一行,计算以该行作为底边的最大全 $1$ 子矩阵的面积。具体计算逻辑如下:
9090

91-
对于矩阵的某一行,我们记第 $k$ 大元素的值为 $val_k$,其中 $k \geq 1$,那么该行至少有 $k$ 个元素不小于 $val_k$,组成的全 $1$ 子矩阵面积为 $val_k \times k$。从大到小遍历矩阵该行的每个元素,取 $val_k \times k$ 的最大值,更新答案。
91+
对于矩阵的某一行,我们记第 $k$ 大元素的值为 $\text{val}_k$,其中 $k \geq 1$,那么该行至少有 $k$ 个元素不小于 $\text{val}_k$,组成的全 $1$ 子矩阵面积为 $\text{val}_k \times k$。从大到小遍历矩阵该行的每个元素,取 $\text{val}_k \times k$ 的最大值,更新答案。
9292

93-
时间复杂度 $O(m \times n \times \log n)$。其中 $m$ 和 $n$ 分别为矩阵的行数和列数
93+
时间复杂度 $O(m \times n \times \log n)$,空间复杂度 $O(\log n)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数
9494

9595
<!-- tabs:start -->
9696

solution/1700-1799/1727.Largest Submatrix With Rearrangements/README_EN.md

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -70,15 +70,15 @@ The largest submatrix of 1s, in bold, has an area of 3.
7070

7171
### Solution 1: Preprocessing + Sorting
7272

73-
Since the matrix is rearranged by columns according to the problem, we can first preprocess each column of the matrix.
73+
Since the matrix can be rearranged by columns, we can preprocess each column of the matrix first.
7474

75-
For each element with a value of $1$, we update its value to the maximum consecutive number of $1$s above it, that is, $matrix[i][j] = matrix[i-1][j] + 1$.
75+
For each element with value $1$, we update its value to the maximum number of consecutive $1$s above it (including itself), i.e., $\text{matrix}[i][j] = \text{matrix}[i-1][j] + 1$.
7676

77-
Next, we can sort each row of the updated matrix. Then traverse each row, calculate the area of the largest sub-matrix full of $1$s with this row as the bottom edge. The specific calculation logic is as follows:
77+
Next, we sort each row of the updated matrix. Then we traverse each row and compute the maximum area of an all-$1$ submatrix with that row as the bottom edge. The detailed calculation is as follows:
7878

79-
For a row of the matrix, we denote the value of the $k$-th largest element as $val_k$, where $k \geq 1$, then there are at least $k$ elements in this row that are not less than $val_k$, forming a sub-matrix full of $1$s with an area of $val_k \times k$. Traverse each element of this row from large to small, take the maximum value of $val_k \times k$, and update the answer.
79+
For a given row, let the $k$-th largest element be $\text{val}_k$, where $k \geq 1$. Then there are at least $k$ elements in that row no less than $\text{val}_k$, forming an all-$1$ submatrix with area $\text{val}_k \times k$. We iterate through the elements of the row from largest to smallest, take the maximum value of $\text{val}_k \times k$, and update the answer.
8080

81-
The time complexity is $O(m \times n \times \log n)$. Here, $m$ and $n$ are the number of rows and columns of the matrix, respectively.
81+
The time complexity is $O(m \times n \times \log n)$ and the space complexity is $O(\log n)$, where $m$ and $n$ are the number of rows and columns of the matrix, respectively.
8282

8383
<!-- tabs:start -->
8484

solution/1700-1799/1728.Cat and Mouse II/README.md

Lines changed: 278 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -143,7 +143,7 @@ tags:
143143

144144
当所有状态的结果都更新完毕时,初始状态的结果即为最终结果。
145145

146-
时间复杂度 $O(m^2 \times n^2 \times (m + n)$,空间复杂度 $O(m^2 \times n^2)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
146+
时间复杂度 $O(m^2 \times n^2 \times (m + n))$,空间复杂度 $O(m^2 \times n^2)$。其中 $m$ 和 $n$ 分别是矩阵的行数和列数。
147147

148148
<!-- tabs:start -->
149149

@@ -600,6 +600,283 @@ func getPrevStates(gMouse, gCat [][]int, m, c, t int, ans [][][]int) [][]int {
600600
}
601601
```
602602

603+
#### TypeScript
604+
605+
```ts
606+
function canMouseWin(grid: string[], catJump: number, mouseJump: number): boolean {
607+
const m = grid.length
608+
const n = grid[0].length
609+
610+
let catStart = 0
611+
let mouseStart = 0
612+
let food = 0
613+
614+
const dirs = [-1, 0, 1, 0, -1]
615+
616+
const gMouse: number[][] = Array.from({ length: m * n }, () => [])
617+
const gCat: number[][] = Array.from({ length: m * n }, () => [])
618+
619+
for (let i = 0; i < m; i++) {
620+
for (let j = 0; j < n; j++) {
621+
const c = grid[i][j]
622+
623+
if (c === '#') continue
624+
625+
const v = i * n + j
626+
627+
if (c === 'C') catStart = v
628+
else if (c === 'M') mouseStart = v
629+
else if (c === 'F') food = v
630+
631+
for (let d = 0; d < 4; d++) {
632+
const a = dirs[d]
633+
const b = dirs[d + 1]
634+
635+
for (let k = 0; k <= mouseJump; k++) {
636+
const x = i + k * a
637+
const y = j + k * b
638+
639+
if (!(0 <= x && x < m && 0 <= y && y < n && grid[x][y] !== '#')) break
640+
641+
gMouse[v].push(x * n + y)
642+
}
643+
644+
for (let k = 0; k <= catJump; k++) {
645+
const x = i + k * a
646+
const y = j + k * b
647+
648+
if (!(0 <= x && x < m && 0 <= y && y < n && grid[x][y] !== '#')) break
649+
650+
gCat[v].push(x * n + y)
651+
}
652+
}
653+
}
654+
}
655+
656+
function getPrevStates(m: number, c: number, t: number, ans: number[][][]): number[][] {
657+
const pt = t ^ 1
658+
const pre: number[][] = []
659+
660+
if (pt === 1) {
661+
for (const pc of gCat[c]) {
662+
if (ans[m][pc][1] === 0) pre.push([m, pc, pt])
663+
}
664+
} else {
665+
for (const pm of gMouse[m]) {
666+
if (ans[pm][c][0] === 0) pre.push([pm, c, pt])
667+
}
668+
}
669+
670+
return pre
671+
}
672+
673+
function calc(): number {
674+
const N = m * n
675+
676+
const degree: number[][][] = Array.from({ length: N }, () =>
677+
Array.from({ length: N }, () => [0, 0])
678+
)
679+
680+
const ans: number[][][] = Array.from({ length: N }, () =>
681+
Array.from({ length: N }, () => [0, 0])
682+
)
683+
684+
for (let i = 0; i < N; i++) {
685+
for (let j = 0; j < N; j++) {
686+
degree[i][j][0] = gMouse[i].length
687+
degree[i][j][1] = gCat[j].length
688+
}
689+
}
690+
691+
const q: number[][] = []
692+
693+
for (let i = 0; i < N; i++) {
694+
ans[food][i][1] = 1
695+
ans[i][food][0] = 2
696+
ans[i][i][1] = 2
697+
ans[i][i][0] = 2
698+
699+
q.push([food, i, 1])
700+
q.push([i, food, 0])
701+
q.push([i, i, 0])
702+
q.push([i, i, 1])
703+
}
704+
705+
while (q.length) {
706+
const [mPos, cPos, t] = q.shift()!
707+
const currentAns = ans[mPos][cPos][t]
708+
709+
for (const [pm, pc, pt] of getPrevStates(mPos, cPos, t, ans)) {
710+
if (pt === currentAns - 1) {
711+
ans[pm][pc][pt] = currentAns
712+
q.push([pm, pc, pt])
713+
} else {
714+
degree[pm][pc][pt]--
715+
if (degree[pm][pc][pt] === 0) {
716+
ans[pm][pc][pt] = currentAns
717+
q.push([pm, pc, pt])
718+
}
719+
}
720+
}
721+
}
722+
723+
return ans[mouseStart][catStart][0]
724+
}
725+
726+
return calc() === 1
727+
}
728+
```
729+
730+
#### Rust
731+
732+
```rust
733+
impl Solution {
734+
pub fn can_mouse_win(grid: Vec<String>, cat_jump: i32, mouse_jump: i32) -> bool {
735+
let m = grid.len();
736+
let n = grid[0].len();
737+
738+
let grid: Vec<Vec<char>> = grid.iter().map(|s| s.chars().collect()).collect();
739+
740+
let mut cat_start = 0usize;
741+
let mut mouse_start = 0usize;
742+
let mut food = 0usize;
743+
744+
let dirs = [-1, 0, 1, 0, -1];
745+
746+
let mut g_mouse = vec![Vec::<usize>::new(); m * n];
747+
let mut g_cat = vec![Vec::<usize>::new(); m * n];
748+
749+
for i in 0..m {
750+
for j in 0..n {
751+
let c = grid[i][j];
752+
if c == '#' {
753+
continue;
754+
}
755+
756+
let v = i * n + j;
757+
758+
if c == 'C' {
759+
cat_start = v;
760+
} else if c == 'M' {
761+
mouse_start = v;
762+
} else if c == 'F' {
763+
food = v;
764+
}
765+
766+
for d in 0..4 {
767+
let a = dirs[d];
768+
let b = dirs[d + 1];
769+
770+
for k in 0..=mouse_jump {
771+
let x = i as i32 + k * a;
772+
let y = j as i32 + k * b;
773+
774+
if !(x >= 0
775+
&& x < m as i32
776+
&& y >= 0
777+
&& y < n as i32
778+
&& grid[x as usize][y as usize] != '#')
779+
{
780+
break;
781+
}
782+
783+
g_mouse[v].push((x as usize) * n + y as usize);
784+
}
785+
786+
for k in 0..=cat_jump {
787+
let x = i as i32 + k * a;
788+
let y = j as i32 + k * b;
789+
790+
if !(x >= 0
791+
&& x < m as i32
792+
&& y >= 0
793+
&& y < n as i32
794+
&& grid[x as usize][y as usize] != '#')
795+
{
796+
break;
797+
}
798+
799+
g_cat[v].push((x as usize) * n + y as usize);
800+
}
801+
}
802+
}
803+
}
804+
805+
use std::collections::VecDeque;
806+
807+
let n2 = m * n;
808+
809+
let mut degree = vec![vec![vec![0i32; 2]; n2]; n2];
810+
let mut ans = vec![vec![vec![0i32; 2]; n2]; n2];
811+
812+
for i in 0..n2 {
813+
for j in 0..n2 {
814+
degree[i][j][0] = g_mouse[i].len() as i32;
815+
degree[i][j][1] = g_cat[j].len() as i32;
816+
}
817+
}
818+
819+
let mut q = VecDeque::new();
820+
821+
for i in 0..n2 {
822+
ans[food][i][1] = 1;
823+
ans[i][food][0] = 2;
824+
ans[i][i][1] = 2;
825+
ans[i][i][0] = 2;
826+
827+
q.push_back((food, i, 1));
828+
q.push_back((i, food, 0));
829+
q.push_back((i, i, 0));
830+
q.push_back((i, i, 1));
831+
}
832+
833+
while let Some((m_pos, c_pos, t)) = q.pop_front() {
834+
let current_ans = ans[m_pos][c_pos][t];
835+
836+
let pt = t ^ 1;
837+
838+
if pt == 1 {
839+
for &pc in &g_cat[c_pos] {
840+
if ans[m_pos][pc][1] != 0 {
841+
continue;
842+
}
843+
844+
if pt as i32 == current_ans - 1 {
845+
ans[m_pos][pc][1] = current_ans;
846+
q.push_back((m_pos, pc, 1));
847+
} else {
848+
degree[m_pos][pc][1] -= 1;
849+
if degree[m_pos][pc][1] == 0 {
850+
ans[m_pos][pc][1] = current_ans;
851+
q.push_back((m_pos, pc, 1));
852+
}
853+
}
854+
}
855+
} else {
856+
for &pm in &g_mouse[m_pos] {
857+
if ans[pm][c_pos][0] != 0 {
858+
continue;
859+
}
860+
861+
if pt as i32 == current_ans - 1 {
862+
ans[pm][c_pos][0] = current_ans;
863+
q.push_back((pm, c_pos, 0));
864+
} else {
865+
degree[pm][c_pos][0] -= 1;
866+
if degree[pm][c_pos][0] == 0 {
867+
ans[pm][c_pos][0] = current_ans;
868+
q.push_back((pm, c_pos, 0));
869+
}
870+
}
871+
}
872+
}
873+
}
874+
875+
ans[mouse_start][cat_start][0] == 1
876+
}
877+
}
878+
```
879+
603880
<!-- tabs:end -->
604881

605882
<!-- solution:end -->

0 commit comments

Comments
 (0)