*leetcode 1111. 有效括号的嵌套深度

【题目】1111. 有效括号的嵌套深度

有效括号字符串 定义:对于每个左括号,都能找到与之对应的右括号,反之亦然。详情参见题末「有效括号字符串」部分。
嵌套深度 depth 定义:即有效括号字符串嵌套的层数,depth(A) 表示有效括号字符串 A 的嵌套深度。详情参见题末「嵌套深度」部分。

给你一个「有效括号字符串」 seq,请你将其分成两个不相交的有效括号字符串,A 和 B,并使这两个字符串的深度最小。

  • 不相交:每个 seq[i] 只能分给 A 和 B 二者中的一个,不能既属于 A 也属于 B 。
  • A 或 B 中的元素在原字符串中可以不连续。
  • A.length + B.length = seq.length
  • max(depth(A), depth(B)) 的可能取值最小。

划分方案用一个长度为 seq.length 的答案数组 answer 表示,编码规则如下:

  • answer[i] = 0,seq[i] 分给 A 。
  • answer[i] = 1,seq[i] 分给 B 。
  • 如果存在多个满足要求的答案,只需返回其中任意 一个 即可。

示例 1:

输入:seq = "(()())"
输出:[0,1,1,1,1,0]

示例 2:

输入:seq = "()(())()"
输出:[0,0,0,1,1,0,1,1]

提示:1 <= text.size <= 10000

有效括号字符串:

仅由 "(" 和 ")" 构成的字符串,对于每个左括号,都能找到与之对应的右括号,反之亦然。
下述几种情况同样属于有效括号字符串:

  1. 空字符串
  2. 连接,可以记作 AB(A 与 B 连接),其中 A 和 B 都是有效括号字符串
  3. 嵌套,可以记作 (A),其中 A 是有效括号字符串
嵌套深度:

类似地,我们可以定义任意有效括号字符串 s 的 嵌套深度 depth(S):

  1. s 为空时,depth("") = 0
  2. s 为 A 与 B 连接时,depth(A + B) = max(depth(A), depth(B)),其中 A 和 B 都是有效括号字符串
  3. s 为嵌套情况,depth("(" + A + ")") = 1 + depth(A),其中 A 是有效括号字符串

例如:"","()()",和 "()(()())" 都是有效括号字符串,嵌套深度分别为 0,1,2,而 ")(" 和 "(()" 都不是有效括号字符串。

【解题思路1】按下标就分配

这个题目读完感觉……很迷……
根据题解和评论,大概是,不相交是说同一个元素不能同时被A和B拥有,A和B括号没有交叠,实际上字符串里的括号字符是随便拿出来进行组合的只是组合之后的A,B都必须是有效的括号。说白了就是分两组,两组的最大深度尽量小,而一人一半最小。
深度就是指嵌套的括号层数,比如“()”深度为1,“(())”深度为2,这道题不用算深度。

ans[idx++] = c == '(' ? idx & 1 : ((idx + 1) & 1); 位与运算,如果idx为偶数则idx&1=0,若为奇数则idx&1=1。

  • 对 ‘(’ 进行 idx&1,也就是按下标奇偶,来决定放进A还是B,奇数层的 ‘(’ 的下标是偶数偶数层的 ‘(’ 的下标是奇数
  • 然后对 ‘)’ 进行 (idx+1)&1 操作保证和对应的 ‘(’ 分在同一组里。 因为 ‘()’ 都是成对出现的,所以即使一对 ‘()’ 中间有嵌套括号,那也一定是占偶数个位置,所以 ‘(’ 和 ‘)’ 的下标总是一奇一偶的。

示例:

括号序列   ( ( ) ( ( ) ) ( ) )
下标编号   0 1 2 3 4 5 6 7 8 9
嵌套深度   1 2 2 2 3 3 2 2 2 1
将奇数深度的分一组用0标记,将偶数深度的括号分一组用1标记。
标记结果   0 1 1 1 0 0 1 1 1 0

找了一下规律发现,原括号字符串里不同深度的左括号的下标会奇偶交替出现,比如深度1的下标是偶数(第一个下标一定是0),深度2的下标是奇数,深度3的下标是偶数,深度4的下标是奇数……
如果是相邻的括号对“()()”,深度是不会增加的,因此把这种括号放到哪一组都没影响,不会增加这一组的深度。但是如果是“(())”连续的两个左括号,会导致深度增加,不同深度的左括号的index是奇偶也是交替出现的,所以交替放到不同组,0和1代表对应左括号的深度最多差1,保证最大深度最小。

public class Solution {
    public int[] maxDepthAfterSplit(String seq) {
        int[] ans = new int [seq.length()];
        int idx = 0;
        for(char c: seq.toCharArray()) {
            ans[idx++] = c == '(' ? idx & 1 : ((idx + 1) & 1);
        }
        return ans;
    }
}

【解题思路2】按深度奇偶分组

遍历括号字符串,每一个括号可以分到A组或B组,分别用0和1表示,使得A组和B组的括号嵌套层数尽量最小就行了。
将奇数深度的括号分成一组,将偶数深度的括号分成一组,分别用0和1标记即可。

public class Solution {
    public int[] maxDepthAfterSplit(String seq) {
        if (seq == null || seq.equals("")){
            return new int[0];
        }
        int depth = 0;
        int[] res = new int[seq.length()];
        for (int i = 0; i < seq.length(); i++) {
            if(seq.charAt(i) == '('){
                depth++; //入栈,栈内深度增加
                res[i] = depth % 2;
            }else{
                res[i] = depth % 2;
                depth--;  //出栈,栈内深度减少
            }
        }
        return res;
    }
}
发布了134 篇原创文章 · 获赞 132 · 访问量 16万+

猜你喜欢

转载自blog.csdn.net/XunCiy/article/details/105245854