2
static Boolean[][][] dp;4
public boolean hasValidPath(char[][] grid) {5
int m = grid.length, n = grid[0].length;6
dp = new Boolean[101][101][201]; // [row][col][open-close]7
if (grid[0][0] == ')') { // cannot start with ')'10
if (grid[m - 1][n - 1] == '(') { // cannot end with '('13
return solve(grid, 0, 0, m, n, 0, 0);16
public static boolean solve(char[][] grid, int i, int j, int m, int n, int open, int close) {17
if (grid[i][j] == '(') {23
> open) { // at any point if closeBracket count exceeds openBracket count then return false24
// since this path can never lead to valid paranthesis string29
== n - 1) { // on reaching bottom right cell if openCount == closeCount return true else33
if (dp[i][j][open - close] != null) { // check for precomputed overlapping subproblem34
return dp[i][j][open - close];36
if (i == m - 1) { // make sure to not go out of the grid in last row37
return dp[i][j][open - close] = solve(grid, i, j + 1, m, n, open, close);39
if (j == n - 1) { // make sure to not go out of the grid in last col40
return dp[i][j][open - close] = solve(grid, i + 1, j, m, n, open, close);43
solve(grid, i + 1, j, m, n, open, close)45
grid, i, j + 1, m, n, open,46
close); // we have two choices to move forward, [i+1][j] or [i][j+1]47
return dp[i][j][open - close] = op;