当前位置:首页 > CN2资讯 > 正文内容

[LeetCode] 1111. Maximum Nesting Depth of Two Valid Parentheses Strings

3天前CN2资讯

A string is a valid parentheses string (denoted VPS) if and only if it consists of "(" and ")" characters only, and:

  • It is the empty string, or
  • It can be written as AB (A concatenated with B), where A and B are VPS's, or
  • It can be written as (A), where A is a VPS.

We can similarly define the nesting depth depth(S) of any VPS S as follows:

  • depth("") = 0
  • depth(A + B) = max(depth(A), depth(B)), where A and B are VPS's
  • depth("(" + A + ")") = 1 + depth(A), where A is a VPS.

For example,  "", "()()", and "()(()())" are VPS's (with nesting depths 0, 1, and 2), and ")(" and "(()" are not VPS's.

Given a VPS seq, split it into two disjoint subsequences A and B, such that A and B are VPS's (and A.length + B.length = seq.length).

Now choose any such A and B such that max(depth(A), depth(B)) is the minimum possible value.

Return an answer array (of length seq.length) that encodes such a choice of A and B:  answer[i] = 0 if seq[i] is part of A, else answer[i] = 1.  Note that even though multiple answers may exist, you may return any of them.

Example 1:

Input: seq = "(()())" Output: [0,1,1,1,1,0]

Example 2:

Input: seq = "()(())()" Output: [0,0,0,1,1,0,1,1] 

Constraints:

  • 1 <= seq.size <= 10000

有效括号的嵌套深度。题意是给一个用字符串表示的嵌套括号,请将input分成两个不相交的子序列,使得这两个子序列的嵌套深度的差值尽可能小。最后输出一个跟input一样长的数组,用0和1记录这两个子序列是怎么分的。

这个题二刷的时候完全没看懂自己写的是什么(????),我这里重新写一下。这个题的描述其实写的不是很好,我这里用一个例子帮助说明。首先,input给的一定是一个有效的括号组合;其次,题目要求的是你把他分成两个不相交的子序列,这里所谓的不相交的意思是input中任何一个左括号或者右括号不能同时出现在两个子序列中。例子,比如"( ( ) ( ) )"你可以分成"()"和"()()",但是你不能分成这样,"( ( ) )"和"( ( ) )"。或者这样理解,input中的任何一个括号不能同时出现在两个子序列中。

这个题目要用到栈,跟20题类似,需要通过判断遍历的是左括号还是右括号来判断深度。相信如下这个例子可以把深度的定义说清楚。

维护一个栈 s,从左至右遍历括号字符串中的每一个字符:

如果当前字符是 (,就把 ( 压入栈中,此时这个 ( 的嵌套深度为栈的高度;

如果当前字符是 ),此时这个 ) 的嵌套深度为栈的高度,随后再从栈中弹出一个 (。

作者:LeetCode-Solution
链接:https://leetcode-cn.com/problems/maximum-nesting-depth-of-two-valid-parentheses-strings/solution/you-xiao-gua-hao-de-qian-tao-shen-du-by-leetcode-s/
来源:力扣(LeetCode)
著作权归作者所有。商业转载请联系作者获得授权,非商业转载请注明出处。

至于做这道题具体的思路,除了需要一个stack协助处理左括号和右括号的push和pop之外(右括号永远不push进stack),你还需要一个变量记录深度depth。在拿到每个字符(左/右括号)的时候,你需要判断这个字符的深度。拿到深度之后,你需要用深度depth % 2以帮助分组。这个地方用mod操作的逻辑是因为mod 2之后,结果一致的字符一定是同组的。

跑一下引用里面的这个例子,一开始深度depth = 0。前两个左括号放入stack都没什么问题;当下标到i = 2的时候,此时因为是一个右括号,所以此时可以结算了。首先我们看一下此时stack的size = 2,说明有两个左括号,也说明嵌套深度是两层(0和1)。此时从stack弹出一个元素(弹出的逻辑也只是因为当遇到右括号的时候,就可以弹出一个左括号跟他配对),弹出的时候记录一下这个弹出元素的下标(1)。此时判断一下stack的size是否能被2整除,如果能,则把left和i在结果数组的对应位置上置成1。不能被2整除的部分,自然就是0。

时间O(n)

空间O(n)

Java实现

1 class Solution { 2 public int[] maxDepthAfterSplit(String seq) { 3 if (seq == null || seq.isEmpty()) { 4 return new int[0]; 5 } 6 int[] res = new int[seq.length()]; 7 Stack<Integer> stack = new Stack<>(); 8 for (int i = 0; i < seq.length(); i++) { 9 if (seq.charAt(i) == '(') { 10 stack.push(i); 11 } else { 12 int depth = stack.size(); 13 int left = stack.pop(); 14 if (depth % 2 == 0) { 15 res[left] = 1; 16 res[i] = 1; 17 } 18 } 19 } 20 return res; 21 } 22 }

JavaScript实现

1 /** 2 * @param {string} seq 3 * @return {number[]} 4 */ 5 var maxDepthAfterSplit = function(seq) { 6 // corner case 7 if (seq == null || seq.length == 0) { 8 return [0]; 9 } 10 11 // normal case 12 let res = new Array(seq.length).fill(0); 13 let stack = []; 14 for (let i = 0; i < seq.length; i++) { 15 let c = seq.charAt(i); 16 if (c == '(') { 17 stack.push(i); 18 } else { 19 let depth = stack.length; 20 let left = stack.pop(); 21 if (depth % 2 == 0) { 22 res[left] = 1; 23 res[i] = 1; 24 } 25 } 26 } 27 return res; 28 };

不用stack的话,可以用位运算符判断每个字符的深度是否能被2整除,也能达到分组的目的。解释参见代码注释。

Java实现

1 /* 2 同一层次的括号在一起 3 例子: 4 ( ( ) ) ( ) 5 0 1 2 3 4 5 6 0,3和4,5是同一层次的括号, 这样两部分的depth都是1, 作差的绝对值为0 7 但是如果0,3和1,2放在一组, 那么这部分的depth=2, 另一部分depth=1, 两部分depth作差的绝对值为1 8 9 应该将同一层次的括号放到一起 10 同一层次的左括号的下标的奇偶性相同, 以左括号为参照, 比如0,3和4,5, 属于偶数层的括号; 1,2属于奇数层的括号 11 其实将括号分成了两大类, 奇数层次的括号, 偶数层次的括号 12 将奇数层次的括号放在一起, 将偶数层次的括号放在一起 13 */ 14 class Solution { 15 public int[] maxDepthAfterSplit(String seq) { 16 int n = seq.length(); 17 int[] arr = new int[n]; 18 for (int i = 0; i < n; i++) { 19 if (seq.charAt(i) == '(') { 20 //奇数层的左括号赋值为1, 偶数层的左括号赋值为0 21 arr[i] = i & 1; 22 } else { 23 //奇数层的右括号的索引是偶数, 需要对该变量赋值为1; 偶数层的右括号的索引是奇数, 需要对改变量赋值为0 24 arr[i] = (i - 1) & 1; 25 } 26 } 27 return arr; 28 } 29 }

相关题目

20. Valid Parentheses

678. Valid Parenthesis String

1111. Maximum Nesting Depth of Two Valid Parentheses Strings

921. Minimum Add to Make Parentheses Valid

1541. Minimum Insertions to Balance a Parentheses String

LeetCode 题目总结

    你可能想看:

    扫描二维码推送至手机访问。

    版权声明:本文由皇冠云发布,如需转载请注明出处。

    本文链接:https://www.idchg.com/info/18654.html

    分享给朋友:

    “[LeetCode] 1111. Maximum Nesting Depth of Two Valid Parentheses Strings” 的相关文章

    Hetzner VPS:高性能、低延迟的全球服务器解决方案

    公司背景与数据中心位置 Hetzner作为欧洲最大的数据中心运营商之一,一直以提供高性能的VPS和独立服务器而闻名。公司在德国、芬兰和美国设有数据中心,确保用户能够享受到低延迟和高带宽的服务。这些数据中心的地理位置选择非常讲究,不仅覆盖了欧洲的主要市场,还通过美国的数据中心服务全球用户。无论你是欧洲...

    DMIT VPS怎么样?性能与价格的全面评测

    在选择VPS的时候,性能绝对是一个关键因素。对于DMIT VPS,我从多个层面来进行评测,特别是它的处理器和存储配置。DMIT采用的Intel至强处理器,真的是一大亮点。这种处理器在处理高负载任务时表现十分优越,其稳定性和速度都让人印象深刻。而且,配合全SSD RAID存储方案,数据的读写速度得到了...

    探索诸暨市:地理特征、气候与经济发展全面分析

    我发现诸暨市,这个位于浙江省中北部的县级市,真是一个令人着迷的地方。它东靠嵊州市,南面与东阳、义乌和浦江相邻,西面与桐庐和富阳相接,北边则与柯桥和萧山为界。这样的地理位置赋予了诸暨市独特的区域特色,方便了与周边城市的交流与发展。 在谈到诸暨的地理特征时,不得不提其独特的地形地貌。诸暨市位于浙东南和浙...

    CloudCone邮箱使用指南:申请、设置与故障排除全攻略

    什么是CloudCone邮箱? CloudCone邮箱是隶属于CloudCone主机商的邮箱系统,该公司成立于2014年,主要提供各类主机服务,包括Linux VPS、Windows VPS和独立服务器。CloudCone的业务重心在于美国洛杉矶机房,以其按小时计费的灵活性而受到用户欢迎。这种收费模...

    深入了解DC9飞机的历史、技术特点与运营经验

    DC9概述 了解DC9这款飞机,首先得从它的历史说起。DC9,或称道格拉斯DC-9,是由道格拉斯飞机公司设计制造的中短程单通道喷气式客机。这款飞机的诞生可以追溯到20世纪60年代。道格拉斯公司在这段时间逐步崛起,骄傲地推出了DC9作为回应当时日益增长的民航市场需求。最初的设计版本虽然体积不大,但凭借...

    深度解析韩国makemodel:传统与现代结合的时尚理念

    markdown格式的内容 韩国makemodel概念 谈到韩国makemodel,我首先感受到了它所传递的深厚文化底蕴。这一时尚理念融合了传统与现代,不仅仅是对衣物的设计,更是一种对韩国文化的致敬。它通过巧妙的配搭,将历史悠久的韩服元素与现代流行趋势相结合,创造出一种独特的美学风格。每一件作品都像...