LeetCode 1111. 有效括号的嵌套深度

该博客详细解释了LeetCode 1111题目的背景和要求,讨论如何将有效括号字符串分割为两部分,使得嵌套深度最小。博主分享了一种解决方案,通过分析括号的位置决定它们属于A还是B子序列,以达到最小深度的目标。文章还提及了最初的错误理解,并提出了有效的匹配策略。
摘要由CSDN通过智能技术生成

题目描述

有效括号字符串 仅由 “(” 和 “)” 构成,并符合下述几个条件之一:

空字符串:s 为空时,depth("") = 0。

连接,可以记作 AB(A 与 B 连接),其中 A 和 B 都是有效括号字符串:s 为 A 与 B 连接时,depth(A + B) = max(depth(A), depth(B)),其中 A 和 B 都是有效括号字符串。

嵌套,可以记作 (A),其中 A 是有效括号字符串:s 为嵌套情况,depth("(" + A + “)”) = 1 + depth(A),其中 A 是有效括号字符串。

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

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

题目:
给你一个有效括号字符串 seq,将其分成两个不相交的子序列 A 和 B,且 A 和 B 满足有效括号字符串的定义(注意:A.length + B.length = seq.length)。

现在,你需要从中选出 任意 一组有效括号字符串 A 和 B,使 max(depth(A), depth(B)) 的可能取值最小。

返回长度为 seq.length 答案数组 answer ,选择 A 还是 B 的编码规则是:如果 seq[i] 是 A 的一部分,那么 answer[i] = 0。否则,answer[i] = 1。即便有多个满足要求的答案存在,你也只需返回 一个。

示例 1:
输入:seq = “(()())”
输出:[0,1,1,1,1,0]

示例 2:
输入:seq = “()(())()”
输出:[0,0,0,1,1,0,1,1]

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

我的思路:一开始我以为是数据结构的那种括号匹配,直接判断’(‘所在的深度,然而,我错了。
它的意思是将这个seq有效地分配到A和B中,A中的元素全部为‘0’,B中的元素全部为’1’。
怎么分的有效呢?为了保证深度最小,这个有点类似榴莲千层蛋糕一样,你吃一层(A,奇数层),我吃一层(B,偶数层),咱俩只能你比我吃得多一层(少一层),也就是说,如果’('所在的深度为奇数,那么就是A里面的元素,反之,为B里面的元素。

代码

class Solution {
    public int[] maxDepthAfterSplit(String seq) {
            char[] seq2=seq.toCharArray();
            int[] deep=new int[seq.length()];
            int count=0;
            for(int i=0;i<seq.length();i++)
            {
                if(seq2[i]=='(')
                {
                    deep[i]=(++count)%2;
                } 
                else
                {
                    deep[i]=(count--)%2;
                }
            }
        return deep;
    }
}

在这里插入图片描述
小结:
结果测出来以后,顿时觉得有点庆幸,庆幸这个题的给出的是"有效字符串seq"而不是给出一个还需要判断是否"有效"的字符串(包含{},[],(),这六种符号),那么怎么使用括号匹配的算法来判断有效呢?
括号匹配算法:

public class _1111 {

    public static void main(String[] args)
        {
            //括号匹配问题
            Scanner scanner = new Scanner(System.in);
            String seq = scanner.next();
            if(!Check_Length(seq))
            {
                System.out.println("输入字符串长度有误!");
            }
            else
            {
                if(Check_bracket(seq))
                {
                    System.out.println("字符匹配!");
                }
                else
                {
                    System.out.println("字符不匹配!");
                }

            }

    }
    private static boolean Check_Length(String seq) {
        return seq.length()%2==0?true:false;
    }
    private static boolean Check_bracket(String seq) {
        List<Integer> list_bracket=new ArrayList<Integer>();
        //首先我们针对()[]{},给他们起个别名
        //(=1
        //)=2
        //[=4
        //]=5
        //{=7
        //}=8
        //为什么要这样起名呢?
        //因为为了在装入list_bracket集合之后,进行匹配消除:也就是,如果list_bracket.get(i+1)-list_bracket.get(i)==1时,我们就说它俩匹配,
        // 届时list_bracket就可以使用remove()消除它俩
        //那么现在你可能会有些疑问,为什么在起别名的时候:让 (=1,)=2,而不是让 (=1,)=1,呢?
        //这是因为我考虑到了这样的情况:(([[{{,显然这个字符串是不匹配的,所以需要对 ( 和 ) 取不同的名字且有联系
        
        for(int i=0;i<seq.length();i++)
        {
            if(seq.charAt(i)=='(')
            {
                list_bracket.add(1);
            }
            if(seq.charAt(i)==')')
            {
                list_bracket.add(2);
            }
            if(seq.charAt(i)=='[')
            {
                list_bracket.add(4);
            }
            if(seq.charAt(i)==']')
            {
                list_bracket.add(5);
            }
            if(seq.charAt(i)=='{')
            {
                list_bracket.add(7);
            }
            if(seq.charAt(i)=='}')
            {
                list_bracket.add(8);
            }
        }
        boolean flag=true;
        while(list_bracket.size()>0&&flag)
        {
            for (int i=0;i<list_bracket.size()-1;i++)
            {
                if(list_bracket.get(i+1)-list_bracket.get(i)==1)
                {
                    list_bracket.remove(i);
                    list_bracket.remove(i);//注意:这个时候不是list_bracket.remove(i+1);,因为list_bracket的size已经改变了
                    flag=true;
                    break;
                }
                else
                {
                    flag=false;
                }
            }
        }
        //剩余的没有消除的括号
        if(list_bracket.size()==0)
        {
            return true;
        }
        else
        {
            return false;
        }
    }


}

结果:
在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值