有效括号问题后续:添加最少括号生成平衡字符串方案咨询
解决最少添加括号生成平衡字符串的递归与DP方案
递归思路
递归核心是把大问题拆成更小的子问题,每次取当前子串的最优解:
- 终止条件:子串为空直接返回空;子串本身是平衡括号则返回原串。
- 分情况处理:
- 若子串首尾字符匹配(如
(和)、[和]),则递归处理中间子串,最终结果为首字符 + 中间子串最优解 + 尾字符。 - 若首尾不匹配,遍历所有拆分点
k(从子串起始到倒数第二个位置),将子串拆分为s[i..k]和s[k+1..j],分别递归求解两个子串的最优解,拼接后取长度最短的结果。 - 针对单个不匹配字符:左括号直接补对应右括号,右括号直接补对应左括号。
- 若子串首尾字符匹配(如
这种思路会自动筛选出添加括号最少的结果,因为每次拆分都取最短的拼接结果。
动态规划(DP)方案
递归存在重复计算问题时,用DP缓存子问题结果可避免重复运算:
定义状态
dp[i][j]表示子串s[i..j]经最少添加括号后得到的平衡字符串。
初始化
- 当
i == j时:- 若
s[i]是左括号((或[),dp[i][j] = s[i] + 对应右括号(如(对应()); - 若
s[i]是右括号,dp[i][j] = 对应左括号 + s[i](如)对应())。
- 若
状态转移
- 先检查首尾字符是否匹配:
- 如果匹配,先计算
temp = s[i] + dp[i+1][j-1] + s[j],后续和拆分结果比较长度取更短的。
- 如果匹配,先计算
- 遍历所有拆分点
k(i ≤ k < j),计算temp_k = dp[i][k] + dp[k+1][j],记录其中长度最短的temp_k。 - 比较
temp(首尾匹配时)和所有temp_k的长度,将最短的字符串赋值给dp[i][j];长度相同时任意选一个即可。
最终结果
dp[0][n-1](n为原字符串长度)就是原字符串的最优解。
示例验证
以"([)]"为例:
- 处理子串
[1..2]("[)]"):初始化dp[1][1] = "[]",dp[2][2] = "()",拆分后拼接得"[]()",或直接补括号得"[()]",两者长度相同,dp[1][2]可任选其一。 - 处理整个串
[0..3]:首尾(和)匹配,若dp[1][2]取"[()]",最终结果为"([()])";若拆分k=1,dp[0][1] = "([])"、dp[2][3] = "()",拼接得"([])()",均符合要求。
内容的提问来源于stack exchange,提问作者Shailendra
相关产品推荐
相关产品推荐

