Skip to content

Commit aed6166

Browse files
authored
feat: add solutions to lc problem: No.1970 (doocs#3549)
No.1970.Last Day Where You Can Still Cross
1 parent 6f14f9b commit aed6166

File tree

12 files changed

+1509
-362
lines changed

12 files changed

+1509
-362
lines changed

solution/1900-1999/1970.Last Day Where You Can Still Cross/README.md

+513-114
Large diffs are not rendered by default.

solution/1900-1999/1970.Last Day Where You Can Still Cross/README_EN.md

+513-114
Large diffs are not rendered by default.
Original file line numberDiff line numberDiff line change
@@ -1,38 +1,46 @@
11
class Solution {
22
public:
3-
vector<int> p;
4-
int dirs[4][2] = {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
5-
int row, col;
6-
73
int latestDayToCross(int row, int col, vector<vector<int>>& cells) {
8-
int n = row * col;
9-
this->row = row;
10-
this->col = col;
11-
p.resize(n + 2);
12-
for (int i = 0; i < p.size(); ++i) p[i] = i;
13-
vector<vector<bool>> grid(row, vector<bool>(col, false));
14-
int top = n, bottom = n + 1;
15-
for (int k = cells.size() - 1; k >= 0; --k) {
16-
int i = cells[k][0] - 1, j = cells[k][1] - 1;
17-
grid[i][j] = true;
18-
for (auto e : dirs) {
19-
if (check(i + e[0], j + e[1], grid)) {
20-
p[find(i * col + j)] = find((i + e[0]) * col + j + e[1]);
4+
int l = 1, r = cells.size();
5+
int g[row][col];
6+
int dirs[5] = {0, 1, 0, -1, 0};
7+
auto check = [&](int k) -> bool {
8+
memset(g, 0, sizeof(g));
9+
for (int i = 0; i < k; ++i) {
10+
g[cells[i][0] - 1][cells[i][1] - 1] = 1;
11+
}
12+
queue<pair<int, int>> q;
13+
for (int j = 0; j < col; ++j) {
14+
if (g[0][j] == 0) {
15+
q.emplace(0, j);
16+
g[0][j] = 1;
17+
}
18+
}
19+
while (!q.empty()) {
20+
auto [x, y] = q.front();
21+
q.pop();
22+
if (x == row - 1) {
23+
return true;
24+
}
25+
for (int i = 0; i < 4; ++i) {
26+
int nx = x + dirs[i];
27+
int ny = y + dirs[i + 1];
28+
if (nx >= 0 && nx < row && ny >= 0 && ny < col && g[nx][ny] == 0) {
29+
q.emplace(nx, ny);
30+
g[nx][ny] = 1;
31+
}
2132
}
2233
}
23-
if (i == 0) p[find(i * col + j)] = find(top);
24-
if (i == row - 1) p[find(i * col + j)] = find(bottom);
25-
if (find(top) == find(bottom)) return k;
34+
return false;
35+
};
36+
while (l < r) {
37+
int mid = (l + r + 1) >> 1;
38+
if (check(mid)) {
39+
l = mid;
40+
} else {
41+
r = mid - 1;
42+
}
2643
}
27-
return 0;
28-
}
29-
30-
bool check(int i, int j, vector<vector<bool>>& grid) {
31-
return i >= 0 && i < row && j >= 0 && j < col && grid[i][j];
32-
}
33-
34-
int find(int x) {
35-
if (p[x] != x) p[x] = find(p[x]);
36-
return p[x];
44+
return l;
3745
}
38-
};
46+
};
Original file line numberDiff line numberDiff line change
@@ -1,45 +1,44 @@
1-
var p []int
2-
31
func latestDayToCross(row int, col int, cells [][]int) int {
4-
n := row * col
5-
p = make([]int, n+2)
6-
for i := 0; i < len(p); i++ {
7-
p[i] = i
8-
}
9-
grid := make([][]bool, row)
10-
for i := 0; i < row; i++ {
11-
grid[i] = make([]bool, col)
12-
}
13-
top, bottom := n, n+1
14-
dirs := [4][2]int{{0, -1}, {0, 1}, {1, 0}, {-1, 0}}
15-
for k := len(cells) - 1; k >= 0; k-- {
16-
i, j := cells[k][0]-1, cells[k][1]-1
17-
grid[i][j] = true
18-
for _, e := range dirs {
19-
if check(i+e[0], j+e[1], grid) {
20-
p[find(i*col+j)] = find((i+e[0])*col + j + e[1])
21-
}
2+
l, r := 1, len(cells)
3+
dirs := [5]int{-1, 0, 1, 0, -1}
4+
check := func(k int) bool {
5+
g := make([][]int, row)
6+
for i := range g {
7+
g[i] = make([]int, col)
228
}
23-
if i == 0 {
24-
p[find(i*col+j)] = find(top)
9+
for i := 0; i < k; i++ {
10+
g[cells[i][0]-1][cells[i][1]-1] = 1
11+
}
12+
q := [][2]int{}
13+
for j := 0; j < col; j++ {
14+
if g[0][j] == 0 {
15+
g[0][j] = 1
16+
q = append(q, [2]int{0, j})
17+
}
2518
}
26-
if i == row-1 {
27-
p[find(i*col+j)] = find(bottom)
19+
for len(q) > 0 {
20+
x, y := q[0][0], q[0][1]
21+
q = q[1:]
22+
if x == row-1 {
23+
return true
24+
}
25+
for i := 0; i < 4; i++ {
26+
nx, ny := x+dirs[i], y+dirs[i+1]
27+
if nx >= 0 && nx < row && ny >= 0 && ny < col && g[nx][ny] == 0 {
28+
g[nx][ny] = 1
29+
q = append(q, [2]int{nx, ny})
30+
}
31+
}
2832
}
29-
if find(top) == find(bottom) {
30-
return k
33+
return false
34+
}
35+
for l < r {
36+
mid := (l + r + 1) >> 1
37+
if check(mid) {
38+
l = mid
39+
} else {
40+
r = mid - 1
3141
}
3242
}
33-
return 0
43+
return l
3444
}
35-
36-
func check(i, j int, grid [][]bool) bool {
37-
return i >= 0 && i < len(grid) && j >= 0 && j < len(grid[0]) && grid[i][j]
38-
}
39-
40-
func find(x int) int {
41-
if p[x] != x {
42-
p[x] = find(p[x])
43-
}
44-
return p[x]
45-
}
Original file line numberDiff line numberDiff line change
@@ -1,49 +1,51 @@
11
class Solution {
2-
private int[] p;
3-
private int row;
4-
private int col;
5-
private boolean[][] grid;
6-
private int[][] dirs = new int[][] {{0, -1}, {0, 1}, {1, 0}, {-1, 0}};
2+
private int[][] cells;
3+
private int m;
4+
private int n;
75

86
public int latestDayToCross(int row, int col, int[][] cells) {
9-
int n = row * col;
10-
this.row = row;
11-
this.col = col;
12-
p = new int[n + 2];
13-
for (int i = 0; i < p.length; ++i) {
14-
p[i] = i;
15-
}
16-
grid = new boolean[row][col];
17-
int top = n, bottom = n + 1;
18-
for (int k = cells.length - 1; k >= 0; --k) {
19-
int i = cells[k][0] - 1, j = cells[k][1] - 1;
20-
grid[i][j] = true;
21-
for (int[] e : dirs) {
22-
if (check(i + e[0], j + e[1])) {
23-
p[find(i * col + j)] = find((i + e[0]) * col + j + e[1]);
24-
}
25-
}
26-
if (i == 0) {
27-
p[find(i * col + j)] = find(top);
28-
}
29-
if (i == row - 1) {
30-
p[find(i * col + j)] = find(bottom);
31-
}
32-
if (find(top) == find(bottom)) {
33-
return k;
7+
int l = 1, r = cells.length;
8+
this.cells = cells;
9+
this.m = row;
10+
this.n = col;
11+
while (l < r) {
12+
int mid = (l + r + 1) >> 1;
13+
if (check(mid)) {
14+
l = mid;
15+
} else {
16+
r = mid - 1;
3417
}
3518
}
36-
return 0;
19+
return l;
3720
}
3821

39-
private int find(int x) {
40-
if (p[x] != x) {
41-
p[x] = find(p[x]);
22+
private boolean check(int k) {
23+
int[][] g = new int[m][n];
24+
for (int i = 0; i < k; i++) {
25+
g[cells[i][0] - 1][cells[i][1] - 1] = 1;
4226
}
43-
return p[x];
44-
}
45-
46-
private boolean check(int i, int j) {
47-
return i >= 0 && i < row && j >= 0 && j < col && grid[i][j];
27+
final int[] dirs = {-1, 0, 1, 0, -1};
28+
Deque<int[]> q = new ArrayDeque<>();
29+
for (int j = 0; j < n; j++) {
30+
if (g[0][j] == 0) {
31+
q.offer(new int[] {0, j});
32+
g[0][j] = 1;
33+
}
34+
}
35+
while (!q.isEmpty()) {
36+
int[] p = q.poll();
37+
int x = p[0], y = p[1];
38+
if (x == m - 1) {
39+
return true;
40+
}
41+
for (int i = 0; i < 4; i++) {
42+
int nx = x + dirs[i], ny = y + dirs[i + 1];
43+
if (nx >= 0 && nx < m && ny >= 0 && ny < n && g[nx][ny] == 0) {
44+
q.offer(new int[] {nx, ny});
45+
g[nx][ny] = 1;
46+
}
47+
}
48+
}
49+
return false;
4850
}
49-
}
51+
}
Original file line numberDiff line numberDiff line change
@@ -1,28 +1,27 @@
11
class Solution:
22
def latestDayToCross(self, row: int, col: int, cells: List[List[int]]) -> int:
3-
n = row * col
4-
p = list(range(n + 2))
5-
grid = [[False] * col for _ in range(row)]
6-
top, bottom = n, n + 1
7-
8-
def find(x):
9-
if p[x] != x:
10-
p[x] = find(p[x])
11-
return p[x]
3+
def check(k: int) -> bool:
4+
g = [[0] * col for _ in range(row)]
5+
for i, j in cells[:k]:
6+
g[i - 1][j - 1] = 1
7+
q = [(0, j) for j in range(col) if g[0][j] == 0]
8+
for x, y in q:
9+
if x == row - 1:
10+
return True
11+
for a, b in pairwise(dirs):
12+
nx, ny = x + a, y + b
13+
if 0 <= nx < row and 0 <= ny < col and g[nx][ny] == 0:
14+
q.append((nx, ny))
15+
g[nx][ny] = 1
16+
return False
1217

13-
def check(i, j):
14-
return 0 <= i < row and 0 <= j < col and grid[i][j]
15-
16-
for k in range(len(cells) - 1, -1, -1):
17-
i, j = cells[k][0] - 1, cells[k][1] - 1
18-
grid[i][j] = True
19-
for x, y in [[0, 1], [0, -1], [1, 0], [-1, 0]]:
20-
if check(i + x, j + y):
21-
p[find(i * col + j)] = find((i + x) * col + j + y)
22-
if i == 0:
23-
p[find(i * col + j)] = find(top)
24-
if i == row - 1:
25-
p[find(i * col + j)] = find(bottom)
26-
if find(top) == find(bottom):
27-
return k
28-
return 0
18+
n = row * col
19+
l, r = 1, n
20+
dirs = (-1, 0, 1, 0, -1)
21+
while l < r:
22+
mid = (l + r + 1) >> 1
23+
if check(mid):
24+
l = mid
25+
else:
26+
r = mid - 1
27+
return l
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
function latestDayToCross(row: number, col: number, cells: number[][]): number {
2+
let [l, r] = [1, cells.length];
3+
const check = (k: number): boolean => {
4+
const g: number[][] = Array.from({ length: row }, () => Array(col).fill(0));
5+
for (let i = 0; i < k; ++i) {
6+
const [x, y] = cells[i];
7+
g[x - 1][y - 1] = 1;
8+
}
9+
const q: number[][] = [];
10+
for (let j = 0; j < col; ++j) {
11+
if (g[0][j] === 0) {
12+
q.push([0, j]);
13+
g[0][j] = 1;
14+
}
15+
}
16+
const dirs: number[] = [-1, 0, 1, 0, -1];
17+
for (const [x, y] of q) {
18+
if (x === row - 1) {
19+
return true;
20+
}
21+
for (let i = 0; i < 4; ++i) {
22+
const nx = x + dirs[i];
23+
const ny = y + dirs[i + 1];
24+
if (nx >= 0 && nx < row && ny >= 0 && ny < col && g[nx][ny] === 0) {
25+
q.push([nx, ny]);
26+
g[nx][ny] = 1;
27+
}
28+
}
29+
}
30+
return false;
31+
};
32+
while (l < r) {
33+
const mid = (l + r + 1) >> 1;
34+
if (check(mid)) {
35+
l = mid;
36+
} else {
37+
r = mid - 1;
38+
}
39+
}
40+
return l;
41+
}

0 commit comments

Comments
 (0)