Skip to content

feat: add solutions to lc problem: No.2267 #3726

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 1 commit into from
Nov 6, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -81,7 +81,17 @@ tags:

<!-- solution:start -->

### 方法一:记忆化搜索
### 方法一:DFS + 剪枝

我们记矩阵的行数为 $m$,列数为 $n$。

如果 $m + n - 1$ 为奇数,或者左上角和右下角的括号不匹配,那么一定不存在合法路径,直接返回 $\text{false}$。

否则,我们设计一个函数 $\textit{dfs}(i, j, k)$,表示从 $(i, j)$ 出发,且当前括号的平衡度为 $k$,是否存在合法路径。其中,平衡度 $k$ 的定义为:从 $(0, 0)$ 到 $(i, j)$ 的路径中,左括号的个数减去右括号的个数。

如果平衡度 $k$ 小于 $0$ 或者大于 $m + n - i - j$,那么一定不存在合法路径,直接返回 $\text{false}$。如果 $(i, j)$ 正好是右下角的格子,那么只有当 $k = 0$ 时才存在合法路径。否则,我们枚举 $(i, j)$ 的下一个格子 $(x, y)$,如果 $(x, y)$ 是合法的格子且 $\textit{dfs}(x, y, k)$ 为 $\text{true}$,那么就存在合法路径。

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

<!-- tabs:start -->

Expand All @@ -91,57 +101,60 @@ tags:
class Solution:
def hasValidPath(self, grid: List[List[str]]) -> bool:
@cache
def dfs(i, j, t):
if grid[i][j] == '(':
t += 1
else:
t -= 1
if t < 0:
def dfs(i: int, j: int, k: int) -> bool:
d = 1 if grid[i][j] == "(" else -1
k += d
if k < 0 or k > m - i + n - j:
return False
if i == m - 1 and j == n - 1:
return t == 0
for x, y in [(i + 1, j), (i, j + 1)]:
if x < m and y < n and dfs(x, y, t):
return k == 0
for a, b in pairwise((0, 1, 0)):
x, y = i + a, j + b
if 0 <= x < m and 0 <= y < n and dfs(x, y, k):
return True
return False

m, n = len(grid), len(grid[0])
if (m + n - 1) % 2 or grid[0][0] == ")" or grid[m - 1][n - 1] == "(":
return False
return dfs(0, 0, 0)
```

#### Java

```java
class Solution {
private boolean[][][] vis;
private int m, n;
private char[][] grid;
private int m;
private int n;
private boolean[][][] vis;

public boolean hasValidPath(char[][] grid) {
m = grid.length;
n = grid[0].length;
if ((m + n - 1) % 2 == 1 || grid[0][0] == ')' || grid[m - 1][n - 1] == '(') {
return false;
}
this.grid = grid;
vis = new boolean[m][n][m + n];
return dfs(0, 0, 0);
}

private boolean dfs(int i, int j, int t) {
if (vis[i][j][t]) {
private boolean dfs(int i, int j, int k) {
if (vis[i][j][k]) {
return false;
}
vis[i][j][t] = true;
t += grid[i][j] == '(' ? 1 : -1;
if (t < 0) {
vis[i][j][k] = true;
k += grid[i][j] == '(' ? 1 : -1;
if (k < 0 || k > m - i + n - j) {
return false;
}
if (i == m - 1 && j == n - 1) {
return t == 0;
return k == 0;
}
int[] dirs = {0, 1, 0};
for (int k = 0; k < 2; ++k) {
int x = i + dirs[k], y = j + dirs[k + 1];
if (x < m && y < n && dfs(x, y, t)) {
final int[] dirs = {1, 0, 1};
for (int d = 0; d < 2; ++d) {
int x = i + dirs[d], y = j + dirs[d + 1];
if (x >= 0 && x < m && y >= 0 && y < n && dfs(x, y, k)) {
return true;
}
}
Expand All @@ -153,28 +166,37 @@ class Solution {
#### C++

```cpp
bool vis[100][100][200];
int dirs[3] = {1, 0, 1};

class Solution {
public:
bool hasValidPath(vector<vector<char>>& grid) {
memset(vis, 0, sizeof(vis));
return dfs(0, 0, 0, grid);
}

bool dfs(int i, int j, int t, vector<vector<char>>& grid) {
if (vis[i][j][t]) return false;
vis[i][j][t] = true;
t += grid[i][j] == '(' ? 1 : -1;
if (t < 0) return false;
int m = grid.size(), n = grid[0].size();
if (i == m - 1 && j == n - 1) return t == 0;
for (int k = 0; k < 2; ++k) {
int x = i + dirs[k], y = j + dirs[k + 1];
if (x < m && y < n && dfs(x, y, t, grid)) return true;
if ((m + n - 1) % 2 || grid[0][0] == ')' || grid[m - 1][n - 1] == '(') {
return false;
}
return false;
bool vis[m][n][m + n];
memset(vis, false, sizeof(vis));
int dirs[3] = {1, 0, 1};
auto dfs = [&](auto&& dfs, int i, int j, int k) -> bool {
if (vis[i][j][k]) {
return false;
}
vis[i][j][k] = true;
k += grid[i][j] == '(' ? 1 : -1;
if (k < 0 || k > m - i + n - j) {
return false;
}
if (i == m - 1 && j == n - 1) {
return k == 0;
}
for (int d = 0; d < 2; ++d) {
int x = i + dirs[d], y = j + dirs[d + 1];
if (x >= 0 && x < m && y >= 0 && y < n && dfs(dfs, x, y, k)) {
return true;
}
}
return false;
};
return dfs(dfs, 0, 0, 0);
}
};
```
Expand All @@ -184,34 +206,37 @@ public:
```go
func hasValidPath(grid [][]byte) bool {
m, n := len(grid), len(grid[0])
if (m+n-1)%2 == 1 || grid[0][0] == ')' || grid[m-1][n-1] == '(' {
return false
}
vis := make([][][]bool, m)
for i := range vis {
vis[i] = make([][]bool, n)
for j := range vis[i] {
vis[i][j] = make([]bool, m+n)
}
}
var dfs func(int, int, int) bool
dfs = func(i, j, t int) bool {
if vis[i][j][t] {
dirs := [3]int{1, 0, 1}
var dfs func(i, j, k int) bool
dfs = func(i, j, k int) bool {
if vis[i][j][k] {
return false
}
vis[i][j][t] = true
vis[i][j][k] = true
if grid[i][j] == '(' {
t += 1
k++
} else {
t -= 1
k--
}
if t < 0 {
if k < 0 || k > m-i+n-j {
return false
}
if i == m-1 && j == n-1 {
return t == 0
return k == 0
}
dirs := []int{1, 0, 1}
for k := 0; k < 2; k++ {
x, y := i+dirs[k], j+dirs[k+1]
if x < m && y < n && dfs(x, y, t) {
for d := 0; d < 2; d++ {
x, y := i+dirs[d], j+dirs[d+1]
if x >= 0 && x < m && y >= 0 && y < n && dfs(x, y, k) {
return true
}
}
Expand All @@ -221,6 +246,53 @@ func hasValidPath(grid [][]byte) bool {
}
```

#### TypeScript

```ts
function hasValidPath(grid: string[][]): boolean {
const m = grid.length,
n = grid[0].length;

if ((m + n - 1) % 2 || grid[0][0] === ')' || grid[m - 1][n - 1] === '(') {
return false;
}

const vis: boolean[][][] = Array.from({ length: m }, () =>
Array.from({ length: n }, () => Array(m + n).fill(false)),
);
const dirs = [1, 0, 1];

const dfs = (i: number, j: number, k: number): boolean => {
if (vis[i][j][k]) {
return false;
}

vis[i][j][k] = true;
k += grid[i][j] === '(' ? 1 : -1;

if (k < 0 || k > m - i + n - j) {
return false;
}

if (i === m - 1 && j === n - 1) {
return k === 0;
}

for (let d = 0; d < 2; ++d) {
const x = i + dirs[d],
y = j + dirs[d + 1];
if (x >= 0 && x < m && y >= 0 && y < n && dfs(x, y, k)) {
return true;
}
}

return false;
};

return dfs(0, 0, 0);
}
```

<!-- tabs:end -->

<!-- solution:end -->
Expand Down
Loading
Loading