题目来自LeetCode,链接:有效括号的嵌套深度。题目描述太长就不搬运了,请自行到原链接查看。
一看到这种括号的题目条件反射般就会想到用栈解决。首先我们需要看这个深度到底咋求,想想栈在处理这种括号的过程中,保留在栈中的左括号的数量不就代表了各个左括号及其匹配的右括号的深度了么,比如(()(())())
,自行模拟整个入栈出栈(即遇到左括号入栈,遇到右括号出栈栈顶的左括号),可知各个括号的深度为1 2 2 2 3 3 2 2 2 1
,对应的就是栈中尚存元素数量。
那咋划分两个括号字符串呢,也很容易,各占一半深度不就好了,可以保证可能的深度最低为原先最大深度的一半。
JAVA版代码如下:
class Solution {
public int[] maxDepthAfterSplit(String seq) {
char[] str = seq.toCharArray();
int strLen = str.length;
if (strLen == 0) {
return new int[0];
}
Stack<Integer> stack = new Stack<>();
int[] result = new int[strLen];
int maxDepth = 0;
stack.push(1);
result[0] = 1;
for (int i = 1; i < strLen; ++i) {
if (str[i] == '(') {
int depth = stack.empty() ? 1 : stack.peek() + 1;
stack.push(depth);
result[i] = depth;
}
else {
int depth = stack.pop();
maxDepth = Math.max(maxDepth, depth);
result[i] = depth;
}
}
int boundary = (maxDepth + 1) / 2;
for (int i = 0; i < strLen; ++i) {
if (result[i] <= boundary) {
result[i] = 0;
}
else {
result[i] = 1;
}
}
return result;
}
}
提交结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/961cf2a17db7a0db05ad81954da66371.png)
上面的代码是初始版本,接下来进行优化,首先是栈没必要真的实现,因为我们实际需要的就只是栈的长度,那用一个变量保存就行了。
JAVA版代码如下:
class Solution {
public int[] maxDepthAfterSplit(String seq) {
char[] str = seq.toCharArray();
int strLen = str.length;
if (strLen == 0) {
return new int[0];
}
int stackLen = 0;
int[] result = new int[strLen];
int maxDepth = 0;
for (int i = 0; i < strLen; ++i) {
if (str[i] == '(') {
result[i] = ++stackLen;
}
else {
maxDepth = Math.max(maxDepth, stackLen);
result[i] = stackLen--;
}
}
int boundary = (maxDepth + 1) / 2;
for (int i = 0; i < strLen; ++i) {
if (result[i] <= boundary) {
result[i] = 0;
}
else {
result[i] = 1;
}
}
return result;
}
}
提交结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/fecbac3ef1bd9e0af1fdc58d566be34b.png)
前面划分两个括号字符串是划分为小于等于一半和大于最大深度两种情况,那实际上可以有另一种划分方法,也就是直接奇偶划分,这样也不用记录最大深度,直接在一次遍历过程中完成。时间复杂度为 O ( n ) O(n) O(n),空间复杂度为 O ( 1 ) O(1) O(1)。
JAVA版代码如下:
class Solution {
public int[] maxDepthAfterSplit(String seq) {
char[] str = seq.toCharArray();
int strLen = str.length;
int stackLen = 0;
int[] result = new int[strLen];
for (int i = 0; i < strLen; ++i) {
if (str[i] == '(') {
result[i] = ++stackLen % 2;
}
else {
result[i] = stackLen-- % 2;
}
}
return result;
}
}
提交结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/34ec0290991e2eb0d73f5553917c4c03.png)
Python版代码如下:
class Solution:
def maxDepthAfterSplit(self, seq: str) -> List[int]:
result = []
stackLen = 0
for s in seq:
if s == '(':
stackLen += 1
result.append(stackLen % 2)
else:
result.append(stackLen % 2)
stackLen -= 1
return result
提交结果如下:
![](https://i-blog.csdnimg.cn/blog_migrate/6da7cc319858c5415945453de233e8ed.png)