leetcode 678 有效的括号字符串
创始人
2025-05-30 08:22:00
0

给定一个只包含三种字符的字符串:( ,) 和 *,写一个函数来检验这个字符串是否为有效字符串。有效字符串具有如下规则:

任何左括号 ( 必须有相应的右括号 )。
任何右括号 ) 必须有相应的左括号 ( 。
左括号 ( 必须在对应的右括号之前 )。
星号 * 可以被视为单个右括号 ) ,或单个左括号 ( ,或一个空字符串。
一个空字符串也被视为有效字符串。
示例 1:

输入: “()”
输出: True
示例 2:

输入: “(*)”
输出: True
示例 3:

输入: “(*))”
输出: True

dp[i][j] 表示字符串 s 从下标 i 到 j 的子串是否为有效的括号字符串, 0≤i≤j

动态规划的边界情况是子串的长度为 1或2的情况:
当子串的长度为 1 时,只有当该字符是 ‘*’ 时,才是有效的括号字符串,此时子串可以看成空字符串;
当子串的长度为 2时,只有当第一个字符是 "(或 * “且第二个字符是 " * 或)” 时,才是有效的括号字符串

当子串的长度大于 2 时,需要根据子串的首尾字符以及中间的字符判断子串是否为有效的括号字符串。只要满足以下一个条件就有可以:
1 如果当s[i] 是 “(或 * “且 s[j]是” * 或)” 时
dp[i+1][j−1]=true 时 dp[i][j]=true,dp[i+1][j−1]=False 时 dp[i][j]=False

2 如果存在 i≤k

时间复杂度:O(n3), 有O(n2)个状态,每个状态的计算时间最多为O(n)。
空间复杂度:O(n2)

class Solution:def checkValidString(self, s: str) -> bool:n = len(s)dp = [[False]*n for _ in range(n)]for i in range(n):if s[i] == '*':dp[i][i] = Truefor i in range(n-1):if (s[i] in ['(', '*']) and (s[i+1] in [')', '*']):dp[i][i+1] = Truefor i in range(n-3, -1, -1):for j in range(i+2, n):if (s[i] in ['(', '*']) and (s[j] in [')', '*']):dp[i][j] = dp[i+1][j-1]for k in range(i, j):if dp[i][k] and dp[k+1][j]:dp[i][j] = True break  return dp[0][n-1]

可以看到时间复杂度比较高,用栈的话能降低。一般遇到括号匹配问题就可以想到栈。
在有星号的情况下,需要两个栈分别存储左括号和星号。从左到右遍历字符串,进行如下操作。
1 如果遇到左括号,则将当前下标存入左括号栈。
2 如果遇到星号,则将当前下标存入星号栈。
3 如果遇到右括号,则需要有一个左括号或星号和右括号匹配,由于星号也可以看成右括号或者空字符串,因此当前的右括号应优先和左括号匹配,没有左括号时和星号匹配:
3.1 如果左括号栈不为空,则从左括号栈弹出栈顶元素;
3.2 如果左括号栈为空且星号栈不为空,则从星号栈弹出栈顶元素;
3.3 如果左括号栈和星号栈都为空,则没有字符可以和当前的右括号匹配,返回 false

遍历结束之后,左括号栈和星号栈可能还有元素。为了将每个左括号匹配,需要将星号看成右括号,且每个左括号必须出现在其匹配的星号之前。当两个栈都不为空时,每次从左括号栈和星号栈分别弹出栈顶元素,对应左括号下标和星号下标,判断左括号下标小于星号下标,如果左括号下标大于星号下标则返回 false。最终判断左括号栈是否为空。如果左括号栈为空,则左括号全部匹配完毕,剩下的星号都可以看成空字符串,此时返回 true。如果左括号栈不为空,则还有左括号无法匹配,此时返回 false。

时间复杂度O(n), 空间复杂度O(n)

class Solution:def checkValidString(self, s: str) -> bool:n = len(s)left_stack, star_stack = [], []for i in range(n):if s[i] == '(':left_stack.append(i)elif s[i] == '*':star_stack.append(i)elif s[i] == ')':if left_stack:left_stack.pop()elif star_stack:star_stack.pop()else:return False i, j = len(left_stack)-1, len(star_stack) - 1while (i >= 0) and (j >= 0):left_index = left_stack.pop()right_index = star_stack.pop()if left_index >= right_index:return Falsei -= 1j -= 1if i < 0:return Trueelse:return False

相关内容

热门资讯

品“百家宴”、玩投壶游戏、制作... 为欢庆传统端午佳节,朝阳区常营畅心园社区精心策划了一场主题活动,居民们纷纷贡献厨艺,“百家宴”热气腾...
台北街亮相昆明 吸引民众品尝台... 5月30日,市民手拿刚买的美食自拍。近日,汇聚蚵仔煎、大肠包小肠、黑糖珍珠奶茶、花生卷冰淇淋等经典台...
原创 鱼... 标题:鱼肉炒猪肉,只有超级大师才做出能吃的 在美食的世界里,每一道菜肴都承载着厨师对食材的尊重与热...
原创 凉... 标题:凉拌莴笋,碧绿爽脆,专治各种没胃口 在炎炎夏日,食欲减退成了许多人的困扰。这时,一道清爽可口...
原创 就... 天热就是喜欢做一些汤菜,有汤有菜,有荤有素的吃起来痛快,开胃又下饭。最近我可分享了不少做法了,如随手...
Android kotlin ... 文章目录 一、实现效果二、项目功能三、引入依赖四、三个实体类(分组/分组的子项/展开收起)五、适配器...
涠洲岛春节跟团游哪家服务好? 春节期间,涠洲岛作为一个独特的海岛旅游目的地,吸引了大量游客前来体验其自然风光和文化魅力。很多人选择...
张家界5天4晚跟团价格,张家界... 去张家界自由行5天4晚需要花多少钱?超省钱攻略分享! 张家界想省钱的一定要看,真实经历记录分享! 在...
嵌入式学习笔记——SysTic... 系统滴答前言SysTick概述SysTick是个啥SysTick结构框图1. 时钟选择2.计数器部分...
康养、温泉、非遗过端午!绿美广... 粽叶飘香时,龙舟竞渡忙。2025年端午假期如约而至,广州乡村与近郊景区已备好丰盛的文旅大餐。从森林康...
Vuex由浅入深详细讲解 目录前言一,理解Vuex1.1 Vuex是什么1.2 Vuex概述1.3 Vuex统一...
conv2d.中 groups... 1. groups 改变的是每个filter中通道数; 使用groups前后ÿ...
3D Slicer学习记录(4... 前记 OpenIGTLink是一个开源网络通信接口,专门为图像引导干预而设计。它的目标是在手术室(o...
武夷山:九曲溪竹筏漂流,丹霞地... 武夷山九曲溪竹筏漂流是一场融合自然与人文的奇妙之旅。乘坐古朴竹筏顺流而下,可饱览鬼斧神工的丹霞地貌,...
04 - 进程参数编程 ---- 整理自狄泰软件唐佐林老师课程 查看所有文章链接:(更新中&...
蓝桥杯备赛 [day01]|p... 目录 0 题目类型  1 迷宫问题 图解 2 乘积尾零 算法解释 用Python处理大数 用C...
STM32:TIM定时器输出比... 一、输出比较简介 1、输出比较 OC(Output Comapre)输出...
武汉白酒批发厂家直销(本地低价... 各位酒友们,近在琢磨着搞点儿武汉白酒本地批发的事儿,这不,就看到了“武汉白酒批发厂家直销(本地低价货...
丰收季的一场原粮溯源之旅:解码... 导读:以“粮”心筑基石,以匠心酿美酒,古井贡酒正引领着中国白酒品质升级的新征程。 五月的亳州,金黄的...
10 分钟出餐!鲜香虾仁蛋炒饭 忙碌的早晨或疲惫的夜晚,想吃顿热乎又美味的主食?这道 10 分钟就能出锅的鲜香虾仁蛋炒饭绝对是救星!...