【C++动态规划 合法括号】2267. 检查是否有合法括号字符串路径|2084
本文涉及知识点
C++动态规划
LeetCode2267. 检查是否有合法括号字符串路径
一个括号字符串是一个 非空 且只包含 ‘(’ 和 ‘)’ 的字符串。如果下面 任意 条件为 真 ,那么这个括号字符串就是 合法的 。
字符串是 () 。
字符串可以表示为 AB(A 连接 B),A 和 B 都是合法括号序列。
字符串可以表示为 (A) ,其中 A 是合法括号序列。
给你一个 m x n 的括号网格图矩阵 grid 。网格图中一个 合法括号路径 是满足以下所有条件的一条路径:
路径开始于左上角格子 (0, 0) 。
路径结束于右下角格子 (m - 1, n - 1) 。
路径每次只会向 下 或者向 右 移动。
路径经过的格子组成的括号字符串是 合法 的。
如果网格图中存在一条 合法括号路径 ,请返回 true ,否则返回 false 。
示例 1:
输入:grid = [[“(”,“(”,“(”],[“)”,“(”,“)”],[“(”,“(”,“)”],[“(”,“(”,“)”]]
输出:true
解释:上图展示了两条路径,它们都是合法括号字符串路径。
第一条路径得到的合法字符串是 “()(())” 。
第二条路径得到的合法字符串是 “((()))” 。
注意可能有其他的合法括号字符串路径。
示例 2:
输入:grid = [[“)”,“)”],[“(”,“(”]]
输出:false
解释:两条可行路径分别得到 “))(” 和 “)((” 。由于它们都不是合法括号字符串,我们返回 false 。
提示:
m == grid.length
n == grid[i].length
1 <= m, n <= 100
grid[i][j] 要么是 ‘(’ ,要么是 ‘)’ 。
合法括号+动态规划
合法括号的另一种表达方式:左括号分值1,右括号分值-1。s的分值0,任意前缀的分值都为0 是合法括号。
动态规划的状态表示
dp[r][c][v] ,以grid[r][c]结尾,分值为v的方案是否存在。空间复杂度:O(nm(n+m))
动态规划的填表顺序
r=0 to m-1 c = 0 to n-1 v =0 to m+n-1
动态规划的转移方程
dp[r][c]不成立,忽略。
v1 =v + grid[r][c+1]的值。如果v1 < 0,忽略。
右移:dp[r][c+1][v1] = true;
下移类似
单个状态转移时间复杂度:O(1)
总时间复杂度:O(mn(m+n))
动态规划的初始值
dp[0][0][1]=true,其它全false。
如果grid[0][0]是反括号,返回false
动态规划的返回值:
dp.back().back()[0]
代码
核心代码
class Solution {public:bool hasValidPath(vector<vector<char>>& grid) {if (\')\' == grid[0][0])return false;const int R = grid.size();const int C = grid[0].size();const int K = R + C;auto S = [&](const char& ch) {return (\'(\' == ch) ? 1 : -1; };vector<vector<vector<bool>>> dp(R, vector<vector<bool>>(C,vector<bool>(K)));dp[0][0][1] = true;auto Add = [&](int r, int c, int kPre) {if (r >= R)return;if (c >= C)return;const int k = kPre + S(grid[r][c]);if (k < 0)return;if (k >= K)return;dp[r][c][k] = true;};for (int r = 0; r < R; r++) {for (int c = 0; c < C; c++) {for (int k = 0; k < R + C; k++) {if (dp[r][c][k]) {Add(r + 1, c, k);Add(r, c+1, k);}}}}return dp.back().back()[0];}};
单元测试
vector<vector<char>> grid;TEST_METHOD(TestMethod11){grid = { {\'(\',\'(\',\'(\'},{\')\',\'(\',\')\'},{\'(\',\'(\',\')\'},{\'(\',\'(\',\')\'} };auto res = Solution().hasValidPath(grid);AssertEx(true, res);}TEST_METHOD(TestMethod12){grid = { {\')\',\')\'},{\'(\',\'(\'} };auto res = Solution().hasValidPath(grid);AssertEx(false, res);}
扩展阅读
视频课程
先学简单的课程,请移步CSDN学院,听白银讲师(也就是鄙人)的讲解。
https://edu.csdn.net/course/detail/38771
如何你想快速形成战斗了,为老板分忧,请学习C#入职培训、C++入职培训等课程
https://edu.csdn.net/lecturer/6176
测试环境
操作系统:win7 开发环境: VS2019 C++17
或者 操作系统:win10 开发环境: VS2022 C++17
如无特殊说明,本算法用**C++**实现。