记录了初步解题思路 以及本地实现代码;并不一定为最优 也希望大家能一起探讨 一起进步
目录
-
-
- [9/28 1614. 括号的最大嵌套深度](#9/28 1614. 括号的最大嵌套深度)
- [9/29 2267. 检查是否有合法括号字符串路径](#9/29 2267. 检查是否有合法括号字符串路径)
- [9/30 1111. 有效括号的嵌套深度](#9/30 1111. 有效括号的嵌套深度)
- [10/1 20. 有效的括号](#10/1 20. 有效的括号)
- [10/2 22. 括号生成](#10/2 22. 括号生成)
- [10/3 32. 最长有效括号](#10/3 32. 最长有效括号)
- [10/4 678. 有效的括号字符串](#10/4 678. 有效的括号字符串)
-
9/28 1614. 括号的最大嵌套深度
遇到一个左括号嵌套深度+1 一个右括号深度-1
记录最大嵌套深度
python
def maxDepth(s):
"""
:type s: str
:rtype: int
"""
ans = 0
cur = 0
for c in s:
if c=="(":
cur+=1
ans = max(ans,cur)
elif c==")":
cur-=1
return ans
9/29 2267. 检查是否有合法括号字符串路径
只能往下或往右,从左上走到右下,沿途格子拼成的括号串必须合法。
合法括号走的过程中右括号不能比左括号多,走到终点时两者要一样多。
路径长度固定是 m+n-1,长度是奇数、起点是右括号、或终点是左括号,直接不可能。
记「走到 (i,j) 时左括号比右括号多几个」,多出来的变成负数就失败;剩下格子就算全是右括号也填不完,也失败。用记忆化避免重复搜索同一格子同一差值。
python
def hasValidPath(grid):
"""
:type grid: List[List[str]]
:rtype: bool
"""
m, n = len(grid), len(grid[0])
if (m + n) % 2 == 0 or grid[0][0] == ")" or grid[m - 1][n - 1] == "(":
return False
vis = [[[False] * (m + n) for _ in range(n)] for _ in range(m)]
def dfs(i, j, k):
k += 1 if grid[i][j] == "(" else -1
if k < 0 or k > m + n - i - j - 2:
return False
if i == m - 1 and j == n - 1:
return True
if vis[i][j][k]:
return False
vis[i][j][k] = True
if i + 1 < m and dfs(i + 1, j, k):
return True
if j + 1 < n and dfs(i, j + 1, k):
return True
return False
return dfs(0, 0, 0)
9/30 1111. 有效括号的嵌套深度
要把有效括号串拆成两组,让两组里更深的那一组尽量浅。
嵌套深度就是当前还没配对的左括号有多少层。一层分给 A、下一层分给 B,交替分,两组深度大约各一半。
遇到左括号按当前层数的奇偶分到一组,再进入下一层;遇到右括号先回到上一层,按那一层的奇偶分到同一组,保证一对括号分在一起。
python
def maxDepthAfterSplit(seq):
"""
:type seq: str
:rtype: List[int]
"""
ans = [0] * len(seq)
x = 0
for i, c in enumerate(seq):
if c == "(":
ans[i] = x & 1
x += 1
else:
x -= 1
ans[i] = x & 1
return ans
10/1 20. 有效的括号
用栈匹配括号:遇到左括号压栈,遇到右括号必须能和栈顶的左括号配成一对,否则不合法。
扫完后栈必须是空的,说明每个左括号都有对应的右括号。
python
def isValid(s):
"""
:type s: str
:rtype: bool
"""
pair = {")": "(", "]": "[", "}": "{"}
st = []
for c in s:
if c in pair:
if not st or st[-1] != pair[c]:
return False
st.pop()
else:
st.append(c)
return not st
10/2 22. 括号生成
依次填入n个括号
从一个开始 s记录当前i个括号所有可能性
在每个合法的括号序列中任何位置可以插入一个完整的括号对
python
def generateParenthesis(n):
"""
:type n: int
:rtype: List[str]
"""
s = set([""])
for i in range(n):
new_s = set()
for exp in s:
for j in range(len(exp)):
new_s.add(exp[:j]+"()"+exp[j:])
new_s.add(exp+"()")
s = new_s
return list(s)
10/3 32. 最长有效括号
栈里记下还没配对的括号下标,先放一个 -1 当作「上一段无效位置」。
遇到左括号,把下标压栈。遇到右括号,弹出栈顶来配对:栈空了说明这个右括号多出来了,它成为新的无效位置;栈里还有东西,当前下标减去栈顶就是这段有效括号的长度,取最大值。
python
def longestValidParentheses(s):
"""
:type s: str
:rtype: int
"""
st = [-1]
ans = 0
for i, c in enumerate(s):
if c == "(":
st.append(i)
else:
st.pop()
if not st:
st.append(i)
else:
ans = max(ans, i - st[-1])
return ans
10/4 678. 有效的括号字符串
星号可以当左括号、右括号或空字符。
用一个区间记下「当前还没配对的左括号可能有多少个」:遇 '(' 上下界都加 1,遇 ')' 都减 1,遇 '*' 下界减 1、上界加 1。
下界小于 0 就当成 0,相当于少把星号当成左括号。上界小于 0 说明右括号太多,不可能合法。扫完后下界必须是 0,才能配平。
python
def checkValidString(s):
"""
:type s: str
:rtype: bool
"""
lo = hi = 0
for c in s:
if c == "(":
lo += 1
hi += 1
elif c == ")":
lo -= 1
hi -= 1
else:
lo -= 1
hi += 1
if hi < 0:
return False
if lo < 0:
lo = 0
return lo == 0