2267. Check if There Is a Valid Parentheses String Path Hard

@problem@discussion
#Array#Dynamic Programming#Matrix



1/**
2 * [2267]  Check if There Is a Valid Parentheses String Path
3 *
4 * A parentheses string is a non-empty string consisting only of '(' and ')'. It is valid if any of the following conditions is true:
5 * 
6 * It is ().
7 * It can be written as AB (A concatenated with B), where A and B are valid parentheses strings.
8 * It can be written as (A), where A is a valid parentheses string.
9 * 
10 * You are given an m x n matrix of parentheses grid. A valid parentheses string path in the grid is a path satisfying all of the following conditions:
11 * 
12 * The path starts from the upper left cell (0, 0).
13 * The path ends at the bottom-right cell (m - 1, n - 1).
14 * The path only ever moves down or right.
15 * The resulting parentheses string formed by the path is valid.
16 * 
17 * Return true if there exists a valid parentheses string path in the grid. Otherwise, return false.
18 * 
19 * Example 1:
20 * <img alt="" src="https://assets.leetcode.com/uploads/2022/03/15/example1drawio.png" style="width: 521px; height: 300px;" />
21 * Input: grid = [["(","(","("],[")","(",")"],["(","(",")"],["(","(",")"]]
22 * Output: true
23 * Explanation: The above diagram shows two possible paths that form valid parentheses strings.
24 * The first path shown results in the valid parentheses string "()(())".
25 * The second path shown results in the valid parentheses string "((()))".
26 * Note that there may be other valid parentheses string paths.
27 *
28 * Example 2:
29 * <img alt="" src="https://assets.leetcode.com/uploads/2022/03/15/example2drawio.png" style="width: 165px; height: 165px;" />
30 * Input: grid = [[")",")"],["(","("]]
31 * Output: false
32 * Explanation: The two possible paths form the parentheses strings "))(" and ")((". Since neither of them are valid parentheses strings, we return false.
33 *
34 * 
35 * Constraints:
36 * m == grid.length
37 * n == grid[i].length
38 * 1 <= m, n <= 100
39 * grid[i][j] is either '(' or ')'.
40 * 
41 */
42pub struct Solution {}
43
44// problem: https://leetcode.com/problems/check-if-there-is-a-valid-parentheses-string-path/
45// discuss: https://leetcode.com/problems/check-if-there-is-a-valid-parentheses-string-path/discuss/?currentPage=1&orderBy=most_votes&query=
46
47// submission codes start here
48
49impl Solution {
50    pub fn has_valid_path(grid: Vec<Vec<char>>) -> bool {
51        
52        let m = grid.len();
53        let n = grid[0].len();
54        //println!("size {} and {}", m, n);
55        if grid[0][0] == ')' || grid[m - 1][n - 1] == '(' || (m + n - 1) % 2 == 1 {
56            return false;
57        }
58        
59        return Self::dfs(&grid, 0, 0, (0, 0), &mut vec![vec![vec![0; m + n]; n]; m]);
60    }
61
62    pub fn dfs(grid: &Vec<Vec<char>>, open: usize, close: usize, current: (usize, usize), dp: &mut Vec<Vec<Vec<isize>>>) -> bool {
63        if close > open {
64            return false;
65        }
66
67        if open + close == grid.len() + grid[0].len() - 1  && open == close{
68            return true;
69        }
70
71        if current.0 >= grid.len() || current.1 >= grid[0].len() {
72            return false
73        }
74
75        if dp[current.0][current.1][open - close] > 0 {
76            println!("reuse");
77            if dp[current.0][current.1][open - close] == 1 {
78                return true;
79            } else {
80                return false;
81            }
82        }
83
84        let mut new_open = open;
85        let mut new_close = close;
86        if grid[current.0][current.1] == '(' {
87            new_open = open + 1;
88        } else {
89            new_close = close + 1;
90        }
91
92        //println!("checking ({},{}) with open {} and close {}", current.0, current.1, new_open, new_close);
93
94        dp[current.0][current.1][open - close] = if Self::dfs(&grid, new_open, new_close, (current.0 + 1, current.1), dp) ||
95         Self::dfs(&grid, new_open, new_close, (current.0, current.1 + 1), dp) {1} else {2};
96
97        return dp[current.0][current.1][open - close] == 1;
98    }
99}
100
101// submission codes end
102
103#[cfg(test)]
104mod tests {
105    use super::*;
106
107    #[test]
108    fn test_2267_1() {
109        let grid = vec!(vec!('(','(','('), vec!(')','(',')'), vec!('(','(',')'), vec!('(','(',')'));
110        print!("Got {}", Solution::has_valid_path(grid))
111    }
112
113    #[test]
114    fn test_2267_2() {
115        let grid = vec!(vec!('(','('), vec!(')','('));
116        print!("Got {}", Solution::has_valid_path(grid))
117    }
118
119    #[test]
120    fn test_2267_3() {
121        let grid = vec!(vec!('(','(',')','(',')','(','(',')','(','(',')',')',')',')',')','(',')','(','(',')','(','(',')',')',')',')',')','(','(','(','('),vec!(')','(','(','(',')','(',')','(','(',')',')',')',')','(',')',')','(','(',')',')','(',')','(',')','(','(',')','(',')','(','('),vec!(')',')','(','(',')','(','(',')',')',')',')','(','(',')',')','(',')','(',')',')','(','(','(',')',')',')','(',')',')','(',')'),vec!('(','(',')','(',')','(','(',')','(','(','(',')',')','(',')','(',')',')',')',')',')',')','(','(',')','(',')','(',')','(','('),vec!(')',')','(',')',')','(','(','(',')',')','(',')','(',')',')',')','(','(','(',')',')','(',')','(',')',')','(','(','(','(',')'),vec!(')',')','(','(',')','(',')','(',')','(',')','(',')',')','(',')','(',')',')','(',')','(','(','(',')','(',')',')',')','(','('),vec!(')','(','(','(','(','(','(',')',')','(','(',')','(',')',')','(',')',')',')','(','(','(',')','(','(',')',')','(',')','(',')'),vec!(')',')','(','(','(','(','(','(','(',')',')','(','(','(','(','(','(','(','(','(','(','(','(',')',')','(','(',')',')','(',')'),vec!('(',')',')',')','(','(',')',')',')',')','(',')',')','(',')',')','(','(','(','(','(','(','(',')',')','(','(',')',')','(','('),vec!('(','(',')','(',')',')',')',')','(','(','(',')',')',')','(',')','(','(',')','(','(','(',')','(','(','(','(','(',')',')',')'),vec!('(',')','(','(','(','(',')','(','(',')',')','(','(',')','(','(','(',')','(','(','(',')',')','(',')',')','(',')','(','(',')'),vec!(')',')','(','(','(','(',')','(','(',')',')','(',')',')','(',')','(','(','(','(','(','(','(',')','(','(',')',')','(','(','('),vec!('(',')',')',')','(',')','(','(','(',')',')',')','(',')','(',')',')','(','(','(','(',')','(',')',')',')',')',')',')','(','('),vec!('(','(','(','(','(','(',')',')','(',')','(','(','(',')',')','(',')','(',')','(',')','(','(','(',')',')',')','(',')','(','('),vec!('(',')',')',')',')','(','(',')',')',')',')',')',')','(','(',')','(',')',')','(',')','(',')',')',')','(','(',')','(','(','('),vec!('(',')',')','(','(',')',')','(',')',')','(','(','(',')',')',')',')','(','(','(',')',')','(',')','(','(','(','(',')',')',')'),vec!(')','(','(',')','(','(',')',')',')','(','(','(','(',')','(',')',')',')','(',')','(',')','(','(',')','(','(','(','(','(','('),vec!('(',')','(',')','(','(',')',')',')',')',')','(','(',')',')','(',')','(',')',')',')',')','(','(','(',')','(',')','(',')',')'),vec!('(',')','(',')',')',')','(','(','(',')','(',')','(','(',')',')','(',')','(',')','(',')','(','(','(','(','(',')','(',')','('),vec!(')',')',')',')',')','(',')',')','(','(',')','(',')',')','(',')',')','(','(','(','(',')','(','(','(','(',')',')',')',')','('),vec!(')','(','(','(','(','(',')','(',')',')',')',')','(','(','(',')',')','(',')',')','(','(','(','(','(','(',')',')','(','(','('),vec!('(','(','(',')',')','(',')','(',')',')',')',')','(',')',')',')',')','(',')','(','(','(','(',')','(','(','(','(','(','(',')'));
122        print!("Got {}", Solution::has_valid_path(grid))
123    }
124}
125


Back
© 2025 bowen.ge All Rights Reserved.