Input: grid =[["(","(","("],[")","(",")"],["(","(",")"],["(","(",")"]]Output: trueExplanation: The above diagram shows two possible paths that form valid parentheses strings.The first path shown results in the valid parentheses string "()(())".The second path shown results in the valid parentheses string "((()))".Note that there may be other valid parentheses string paths.
Input: grid =[[")",")"],["(","("]]Output: falseExplanation: The two possible paths form the parentheses strings "))(" and ")((". Since neither of them are valid parentheses strings, we returnfalse.
We need to find a path from the top-left to the bottom-right of the grid such that the parentheses string formed is valid. Since we can only move right or down, and the string must be valid at every step, we can use dynamic programming to track the possible balances (number of open minus close parentheses) at each cell.
At each cell, the only information that matters is the current balance (open - close) and the position. We can use a set to track all possible balances at each cell, propagating from the top-left to the bottom-right. If a balance of 0 is possible at the end, then a valid path exists. The balance must never be negative (more ‘)’ than ‘(’ at any point), and the final balance must be 0.
Let m and n be the grid dimensions. The path length is m + n - 1.
If the path length is odd, return false (cannot form a valid parentheses string).
Use a DP table where dp[i][j] is a set of possible balances at cell (i, j).
Initialize dp[0][0] with 1 if grid[0][0] == ‘(’, else -1 (invalid if negative).
For each cell, propagate possible balances from the top and left neighbors, updating the balance according to the current cell’s value. Only keep balances >= 0.
At the end, check if a balance of 0 is possible at the bottom-right cell.
classSolution {
public:bool hasValidPath(vector<vector<char>>& grid) {
int m = grid.size(), n = grid[0].size();
if ((m + n -1) %2) return false;
vector<vector<unordered_set<int>>> dp(m, vector<unordered_set<int>>(n));
dp[0][0].insert(grid[0][0] =='('?1:-1);
for (int i =0; i < m; ++i) {
for (int j =0; j < n; ++j) {
for (int d : {0, 1}) {
int ni = i - d, nj = j - (1- d);
if (ni >=0&& nj >=0) {
for (int bal : dp[ni][nj]) {
int nb = bal + (grid[i][j] =='('?1:-1);
if (nb >=0) dp[i][j].insert(nb);
}
}
}
}
}
return dp[m-1][n-1].count(0);
}
};
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
classSolution:
defhas_valid_path(self, grid: list[list[str]]) -> bool:
m, n = len(grid), len(grid[0])
if (m + n -1) %2:
returnFalse dp = [[set() for _ in range(n)] for _ in range(m)]
dp[0][0].add(1if grid[0][0] =='('else-1)
for i in range(m):
for j in range(n):
for ni, nj in ((i-1, j), (i, j-1)):
if0<= ni < m and0<= nj < n:
for bal in dp[ni][nj]:
nb = bal + (1if grid[i][j] =='('else-1)
if nb >=0:
dp[i][j].add(nb)
return0in dp[m-1][n-1]
classSolution {
publicbooleanhasValidPath(char[][] grid) {
int m = grid.length, n = grid[0].length;
if ((m + n - 1) % 2 != 0) returnfalse;
Set<Integer>[][] dp =new HashSet[m][n];
for (int i = 0; i < m; i++) for (int j = 0; j < n; j++) dp[i][j]=new HashSet<>();
dp[0][0].add(grid[0][0]=='('? 1 : -1);
for (int i = 0; i < m; i++) {
for (int j = 0; j < n; j++) {
for (int[] d : newint[][]{{-1,0},{0,-1}}) {
int ni = i + d[0], nj = j + d[1];
if (ni >= 0 && nj >= 0) {
for (int bal : dp[ni][nj]) {
int nb = bal + (grid[i][j]=='('? 1 : -1);
if (nb >= 0) dp[i][j].add(nb);
}
}
}
}
}
return dp[m-1][n-1].contains(0);
}
}
classSolution {
funhasValidPath(grid: Array<CharArray>): Boolean {
val m = grid.size; val n = grid[0].size
if ((m + n - 1) % 2!=0) returnfalseval dp = Array(m) { Array(n) { mutableSetOf<Int>() } }
dp[0][0].add(if (grid[0][0] =='(') 1else -1)
for (i in0 until m) for (j in0 until n) {
for ((di, dj) in listOf(-1 to 0, 0 to -1)) {
val ni = i + di; val nj = j + dj
if (ni in0 until m && nj in0 until n) {
for (bal in dp[ni][nj]) {
val nb = bal + if (grid[i][j] =='(') 1else -1if (nb >=0) dp[i][j].add(nb)
}
}
}
}
return0in dp[m-1][n-1]
}
}
impl Solution {
pubfnhas_valid_path(grid: Vec<Vec<char>>) -> bool {
let m = grid.len();
let n = grid[0].len();
if (m + n -1) %2!=0 {
returnfalse;
}
letmut dp =vec![vec![std::collections::HashSet::new(); n]; m];
dp[0][0].insert(if grid[0][0] =='(' { 1 } else { -1 });
for i in0..m {
for j in0..n {
for (di, dj) in [(-1, 0), (0, -1)] {
let ni = i asisize+ di;
let nj = j asisize+ dj;
if ni >=0&& nj >=0 {
for&bal in&dp[ni asusize][nj asusize] {
let nb = bal +if grid[i][j] =='(' { 1 } else { -1 };
if nb >=0 {
dp[i][j].insert(nb);
}
}
}
}
}
}
dp[m-1][n-1].contains(&0)
}
}