题目描述
分析
u1s1这道题的翻译着实抽象。。。下面是我认为的几个要点:
- 有效括号字符串(Valid Parentheses Strings, 后面简写为VPS)中的括号都是前后匹配的,不会出现类似"())"、")("之类的情况;
- VPS
seq
,要求将其分为两个子串A、B,它们也需要是VPS; - VPS的深度depth
- 空字符,如
""
,depth为0; - 嵌套,如
"(vps)"
,depth为内部vps的depth+1;
例:空字符""
depth为0,则()
depth为1,(())
depth为2; - 连接,如
"vpsA vpsB"
,depth为vpsA与vpsB的最大值;
- 空字符,如
- 题目要求
seq
的两个子串A、B满足\(MAX(depth(A), depth(B))\)最小
一段VPS的深度取决于它嵌套的层数,而将一段深度为D的VPS拆分为两段深度分别为DA与DB的子串,会有\(D == DA + DB\)(和套娃一个道理?)
因此要使得\(MAX(depth(A), depth(B))\)最小,理论上需要\(DA=DB=\frac{1}{2}D\),而实际情况中D并不一定能等分为DA与DB,一次让二者尽可能接近即可,
代码中要将seq的每嵌套交替分配给子串A和B
算法设计
- 计数器
counter
,用来表示还未匹配到")"的"("数 - 标记位
sgn
,用来表示下一个(
应该分配给哪个子串
程序执行:
- 当匹配到
(
:- 将sgn加入到result中,0表示这个
(
分配给了A,1代表分配给了B; - 改变sgn--如果下次匹配到的还是
(
,则说明出现了一层嵌套,要将这个(
分给子串B; - 增加了一个未匹配的前括号,
counter
进行一次自加;
- 将sgn加入到result中,0表示这个
- 当匹配到
)
:- 这一位的
)
应该属于与sgn相异的那个子串,因此将sgn^1
加入到result中; - 一个前括号得到匹配,
counter
自减; - 如果
counter != 0
,则说明下个()
与刚刚匹配完那个括号为连接关系,把它们分配给同一个子串即可,因此要改变sgn
的值;
- 这一位的
C++代码实现:
class Solution {
public:
vector<int> maxDepthAfterSplit(string seq) {
vector<int> result;
short counter = 0;
int sgn = 0;
for(int i = 0; i < seq.size(); i++){
if(seq[i] == '('){
result.push_back(sgn);
sgn ^= 1;
counter ++;
}
if(seq[i] == ')'){
result.push_back(sgn ^ 1);
counter --;
if(counter != 0){
sgn ^= 1;
}
}
}
return result;
}
};