当前位置:网站首页>栈题目:有效括号的嵌套深度
栈题目:有效括号的嵌套深度
2022-07-07 03:09:00 【伟大的车尔尼】
题目
标题和出处
标题:有效括号的嵌套深度
难度
6 级
题目描述
要求
一个字符串是有效括号字符串,当且仅当该字符串只包含 "(" \texttt{"("} "(" 和 ")" \texttt{")"} ")",且满足下列条件之一:
- 字符串是一个空字符串;
- 字符串可以写为 AB \texttt{AB} AB( A \texttt{A} A 与 B \texttt{B} B 字符串连接),其中 A \texttt{A} A 和 B \texttt{B} B 都是有效括号字符串;
- 字符串可以写为 (A) \texttt{(A)} (A),其中 A \texttt{A} A 是一个有效括号字符串。
对于有效括号字符串 S \texttt{S} S,其嵌套深度 depth(S) \texttt{depth(S)} depth(S) 定义如下:
- depth("") = 0 \texttt{depth("")} = 0 depth("")=0;
- depth(A + B) = max(depth(A), depth(B)) \texttt{depth(A + B) = max(depth(A), depth(B))} depth(A + B) = max(depth(A), depth(B)),其中 A \texttt{A} A 和 B \texttt{B} B 都是有效括号字符串;
- depth("(" + A + ")") = 1 + depth(A) \texttt{depth("(" + A + ")") = 1 + depth(A)} depth("(" + A + ")") = 1 + depth(A),其中 A \texttt{A} A 是一个有效括号字符串。
例如, "" \texttt{""} ""、 "()()" \texttt{"()()"} "()()" 和 "()(()())" \texttt{"()(()())"} "()(()())" 是有效括号字符串(嵌套深度分别是 0 \texttt{0} 0、 1 \texttt{1} 1 和 2 \texttt{2} 2), ")(" \texttt{")("} ")(" 和 "(()" \texttt{"(()"} "(()" 不是有效括号字符串。
给定一个有效括号字符串 seq \texttt{seq} seq,将其分成两个不相交的子序列 A \texttt{A} A 和 B \texttt{B} B,使得 A \texttt{A} A 和 B \texttt{B} B 是有效括号字符串,且 A.length + B.length = seq.length \texttt{A.length + B.length = seq.length} A.length + B.length = seq.length。
选择任意的 A \texttt{A} A 和 B \texttt{B} B 使得 max(depth(A), depth(B)) \texttt{max(depth(A), depth(B))} max(depth(A), depth(B)) 的值最小。
返回数组 answer \texttt{answer} answer(长度为 seq.length \texttt{seq.length} seq.length),表示选择 A \texttt{A} A 和 B \texttt{B} B 的编码:如果 seq[i] \texttt{seq[i]} seq[i] 分给 A \texttt{A} A 则 answer[i] = 0 \texttt{answer[i] = 0} answer[i] = 0,否则 answer[i] = 1 \texttt{answer[i] = 1} answer[i] = 1。如果存在多个满足要求的答案,只需返回其中任意一个即可。
示例
示例 1:
输入: seq = "(()())" \texttt{seq = "(()())"} seq = "(()())"
输出: [0,1,1,1,1,0] \texttt{[0,1,1,1,1,0]} [0,1,1,1,1,0]
示例 2:
输入: seq = "()(())()" \texttt{seq = "()(())()"} seq = "()(())()"
输出: [0,0,0,1,1,0,1,1] \texttt{[0,0,0,1,1,0,1,1]} [0,0,0,1,1,0,1,1]
数据范围
- 1 ≤ seq.size ≤ 10000 \texttt{1} \le \texttt{seq.size} \le \texttt{10000} 1≤seq.size≤10000
解法
思路和算法
在考虑将有效括号字符串分成两个不相交的子序列之前,首先需要考虑每个括号所在的嵌套深度。有效括号字符串中,每个左括号都有一个匹配的右括号,一对匹配的左右括号的嵌套深度相同。
为了计算每个括号所在的嵌套深度,可以使用栈存储左括号,根据栈内元素个数得到嵌套深度。从左到右遍历有效括号字符串 seq \textit{seq} seq,遇到左括号则将左括号入栈,遇到右括号则将栈顶的左括号出栈,表示当前的右括号和栈顶的左括号匹配。根据嵌套深度的定义,左括号和右括号的嵌套深度分别计算如下:
对于左括号,在入栈操作之后的栈内元素个数为左括号的嵌套深度;
对于右括号,在出栈操作之前的栈内元素个数为右括号的嵌套深度。
明确括号的嵌套深度的计算方法之后,回到原问题,将有效括号字符串 seq \textit{seq} seq 分成两个不相交的子序列 A A A 和 B B B,使得两个子序列的嵌套深度最小。只要栈内的一半括号属于子序列 A A A,另一半括号属于子序列 B B B,即可满足两个子序列的嵌套深度最小。实现方面,将奇数层的括号分给 A A A,将偶数层的括号分给 B B B 即可。
由于一对匹配的左右括号的嵌套深度相同,因此一对匹配的左右括号一定在同一个子序列中。由此可知,任意一个子序列中的左右括号数量一定相等,且左括号一定出现在与之匹配的右括号之前,因此两个子序列都是有效括号字符串。
由于栈内只存储左括号,因此并不需要真正维护一个栈,只需要记录遍历过程中的嵌套深度即可。
代码
class Solution {
public int[] maxDepthAfterSplit(String seq) {
int length = seq.length();
int[] answer = new int[length];
int depth = 0;
for (int i = 0; i < length; i++) {
if (seq.charAt(i) == '(') {
depth++;
answer[i] = depth % 2 == 1 ? 0 : 1;
} else {
answer[i] = depth % 2 == 1 ? 0 : 1;
depth--;
}
}
return answer;
}
}
复杂度分析
时间复杂度: O ( n ) O(n) O(n),其中 n n n 是字符串 seq \textit{seq} seq 的长度。需要遍历字符串 seq \textit{seq} seq 一次,每次更新嵌套深度的时间都是 O ( 1 ) O(1) O(1)。
空间复杂度: O ( 1 ) O(1) O(1)。除了返回值以外,使用的空间复杂度是常数。
边栏推荐
- Distributed ID solution
- How can clothing stores make profits?
- 大促过后,销量与流量兼具,是否真的高枕无忧?
- MySQL installation
- 从零到一,教你搭建「CLIP 以文搜图」搜索服务(二):5 分钟实现原型
- Installing redis and windows extension method under win system
- unity3d学习笔记
- Answer to the first stage of the assignment of "information security management and evaluation" of the higher vocational group of the 2018 Jiangsu Vocational College skills competition
- 根据IP获取地市
- Stack and queue-p79-9
猜你喜欢
网络基础 —— 报头、封装和解包
mysql查看bin log 并恢复数据
Answer to the first stage of the assignment of "information security management and evaluation" of the higher vocational group of the 2018 Jiangsu Vocational College skills competition
Maze games based on JS
二十岁的我4面拿到字节跳动offer,至今不敢相信
Leetcode T1165: 日志分析
Navicat importing 15g data reports an error [2013 - lost connection to MySQL server during query] [1153: got a packet bigger]
DHCP路由器工作原理
途家、木鸟、美团……民宿暑期战事将起
Etcd database source code analysis -- starting from the start function of raftnode
随机推荐
Take you to brush (niuke.com) C language hundred questions (the first day)
leetcode 509. Fibonacci Number(斐波那契数字)
SVN version management in use replacement release and connection reset
Postgresql源码(59)分析事务ID分配、溢出判断方法
jdbc数据库连接池使用问题
常用函数detect_image/predict
Matlab tips (29) polynomial fitting plotfit
Redhat5 installing vmware tools under virtual machine
Problems and precautions about using data pumps (expdp, impdp) to export and import large capacity tables in Oracle migration
Basic DOS commands
MySQL (x)
What books can greatly improve programming ideas and abilities?
RuntimeError: CUDA error: CUBLAS_STATUS_ALLOC_FAILED when calling `cublasCreate(handle)`问题解决
2018年江苏省职业院校技能大赛高职组“信息安全管理与评估”赛项任务书
Prime partner of Huawei machine test questions
JWT certification
联合索引ABC的几种索引利用情况
from . onnxruntime_ pybind11_ State Import * noqa ddddocr operation error
【luogu P1971】兔兔与蛋蛋游戏(二分图博弈)
请问 flinksql对接cdc时 如何实现计算某个字段update前后的差异 ?