小黑脑补了一种巧妙方法,max(左起左括号可以匹配右括号的滑动窗口结果,右起右括号匹配左括号的的滑动窗口结果),独立解决了一道困难难度的题,NB!!!
小黑代码
class Solution:
def longestValidParentheses(self, s: str) -> int:
def get_res(s):
# 字符串长度
n = len(s)
# 定义窗口栈
q = []
# 定义双指针
head = 0
tail = 0
# 结果变量
res = 0
# 开始进行双指针操作
while tail < n:
# 左括号,入栈
if s[tail] == '(':
q.append(s[tail])
else:
# 栈里有元素,出栈
if q:
q.pop()
# 非法情况,指针跳过,清空栈
else:
head = tail + 1
q = []
tail += 1
if not q and tail - head > res:
res = tail - head
return res
# 将字符串翻转,左右括号颠倒
s_reverse = []
for c in s[::-1]:
if c == '(':
s_reverse.append(')')
else:
s_reverse.append('(')
s_reverse = ''.join(s_reverse)
return max(get_res(s_reverse), get_res(s))
动态规划法
class Solution:
def longestValidParentheses(self, s: str) -> int:
'''
思路:
令dp[i]为第i个字符为结尾对应的有效长度
如果s[i]=='(',有效长度为0,因为以"("为结尾的字符串一定不是有效字符
如果s[i]==')'
假设dp[i-1] = l
如果s[i-l-1]=='('
dp[i] = dp[i-l-2]+l+2(不考虑越界的情况)
如果s[i-l-1]==')'
dp[i] = 0
'''
# 字符串长度
n = len(s)
if not n:
return 0
# 初始化动态规划数组
dp = [0] * n
# 结果变量
res = 0
for i in range(1, n):
if s[i] == ')' :
# 上一个字符为结尾的最长有效子串长度
l = dp[i-1]
# xxx(***)的情况
if i-l-1 >= 0 and s[i-l-1] == '(':
dp[i] = dp[i-1] + 2
if i-l-2 >= 0:
dp[i] += dp[i-l-2]
res = max(dp[i], res)
return res
栈
class Solution:
def longestValidParentheses(self, s: str) -> int:
# 字符串长度
n = len(s)
if not s:
return 0
# 初始化栈,栈顶元素记录以当前第i个字符为结尾,对应有效子串初始位置的前驱字符编号
q = [-1]
# 结果变量
res = 0
# 开始遍历字符串
for i in range(n):
if s[i] == '(':
q.append(i)
else:
q.pop()
# 栈不为空,证明当前字符为结尾的有效子串存在,利用子串长度更新res后续子串的
if q:
res = max(i-q[-1], res)
# 栈不为空,证明当前字符为结尾的有效子串不存在,将当前字符编号作为栈底元素
else:
q.append(i)
return res
滑动窗口法
class Solution:
def longestValidParentheses(self, s: str) -> int:
# 字符串长度
n = len(s)
# 通过滑动窗口,列举左括号大于等于右括号数的子串,记录有效字符串长度
# 窗口双指针
left = 0
right = 0
# 结果变量
res = 0
for i in range(n):
if s[i] == '(':
left += 1
else:
right += 1
if left < right:
left = right = 0
elif left == right:
res = max(res, right*2)
# 反过来
left = 0
right = 0
for i in range(n-1, -1, -1):
if s[i] == ')':
right += 1
else:
left += 1
if left > right:
left = right = 0
elif left == right:
res = max(res, left * 2)
return res
小黑生活(手机相册此部分信息丢失,从各种群聊的聊天记录中扒的)
中午日语学习
第一次练习舞狮子
晚餐干饭,没吃了打包回去晚上仰山后回家吃
仰山防火道爬坡
回家热一下饭,再来瓶啤酒
麦当劳早餐
午餐干饭
午后日语咖啡
舞狮训练
晚餐干饭
前往六里桥按摩
早餐同事请的味多美热巧
又被叫老师了
午餐干饭
午后咖啡
单位的研究生毕业了
六里桥烤冷面
六里桥按摩店来个拔罐
晚上跟深沉被坑儿吃海底捞
喜茶店咖啡前端学习
把没喝完的美式咖啡回家加奶
加密算法学习
一个人看《养蜂人》
跟尚香新世界吃夜宵
早餐干饭
午餐干饭
午后咖啡
报名青岛马拉松,准备抽签
绕单位跑个步,看到CCTV门口围观的人群
睡前来瓶啤酒
紫光园早餐干饭
布置党课会场
收到了同事的喜糖
午餐干饭
午后咖啡
晚餐单位旁边的牛肉拉面
骑车回家广艺转转
骑到磁器口的蓝鲸自习室回忆一下
魔方商城喜茶
剪个清爽的小头
早餐干饭
午餐干饭
午间咖啡
晚餐干饭
新买的洗脚盆到了
麦当劳早餐
午餐干饭
午间咖啡
晚上跟小元同学去丰台科技园吃潮汕牛肉火锅
逛逛商场
午餐干饭
午间咖啡
玩了玩软件,遇到了奇葩的人
晚餐宇飞牛肉面
夜宵跟尚香吃臭豆腐喝霸王
周日跟尚香咖啡厅学习,吃秤砣麻辣烫
麦当劳早餐
上午团拜会彩排
午餐干饭
被教育了一遍哈哈哈
第一次尝试逆向爬虫
晚餐干饭
晚间跑步
夜宵喝个啤酒吃个串
紫光园早餐干饭
午餐干饭
聊天给我惊到了
午间咖啡
晚上跟思琪老师去吃鸡
回家前整个霸王别姬
睡觉前跑个步
早餐紫光园干饭
午餐干饭
午间咖啡
爬虫逆向尝试
晚餐干饭
奥森仰山10攀越野跑
紫光园早餐
午餐干饭
午间咖啡
彩排团拜会舞狮子
晚餐干饭
第一次体验瑜伽私教
紫光园早餐
午餐干饭
做会议的会务工作
晚上跟你恶心逗兄吃重庆火锅
瑜伽团课开肩
晚上跟学长去蓝港吃蓝蛙(聊天记录中图片损坏)
体验个普拉提小班课