【每日算法Day 87】今天我脱单了,所以大家不用做题了!

简介: 【每日算法Day 87】今天我脱单了,所以大家不用做题了!

想啥呢,我哪来的女朋友?今天是愚人节,还是给我老老实实做题吧。

题目链接

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

题目描述

题面太长晦涩不想看,请直接跳到最后一段。

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

  • 空字符串
  • 连接,可以记作 ABAB 连接),其中 AB 都是有效括号字符串
  • 嵌套,可以记作 (A),其中 A 是有效括号字符串

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

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

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

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

现在,你需要从中选出 任意 一组有效括号字符串 AB,使 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]
解释:
拆成 "()" 和 "()()" ,最大嵌套深度为 1

示例2

输入:
seq = "()(())()"
输出:
[0,0,0,1,1,0,1,1]
解释:
拆成 "()()" 和 "()()" ,最大嵌套深度为 1

说明:

  • 1 <= text.size <= 10000

题解

既然想要两个子序列的嵌套深度中较大者尽量小,那么我们最好能够让两个子序列的嵌套深度相同。

再考虑任意一个原序列中嵌套深度为  的合法子序列,我们要想办法把它拆成两半。那么最优的方法肯定是一半嵌套深度为  ,一半是  。这样两个子序列中嵌套深度较大值就是 ,而其它任何分法都会导致较大值大于它。

那么怎么样才能对半分呢?这个其实随意了,但是最为方便的方法就是,嵌套深度为奇数的作为一个子序列,偶数的作为另一个子序列,这样就对半分了,代码还好写。

具体实现上,我们用一个变量  来表示当前括号的嵌套深度,那么遇到左括号就深度加一,遇到右括号嵌套深度就是当前的  ,但是遍历完这个括号之后,深度要减一,然后嵌套深度为奇数的括号位置处标记为 1 就行了。

伪代码也就是:

if c = '('
    cnt := cnt + 1
    mask := cnt&1
else
    mask := cnt&1
    cnt := cnt - 1

简化

其实我们可以注意到,不管是加一还是减一,奇偶性的变化都是一致的,也就是减一之后的奇偶性和加一之后是相同的。

所以我们把减一也变成加一,那么不管遇到什么括号,都是  加一了,那不就变成了下标  了吗?

我们把上面的伪代码按照这种思路改变一下:

if c = '('
    cnt := cnt + 1
    mask := cnt&1
else
    mask := cnt&1
    cnt := cnt + 1

然后用下标 替换掉 :

if c = '('
    mask := (i+1)&1
else
    mask := i&1

继续改写一下,让形式统一一点:

if c = '('
    mask := ~(i&1)
else
    mask := i&1

那么最后就可以把这两种情况合并了,也就是标记值直接就等于 (i&1)^(c='(')

当然我是从代码的角度,从奇偶性推过来的,官方题解是直接严格证明了正确性:

官方题解:LeetCode 1111. 有效括号的嵌套深度[2]

代码

c++

class Solution {
public:
    vector<int> maxDepthAfterSplit(string seq) {
        int cnt = 0;
        vector<int> res;
        for (auto c : seq) {
            if (c == '(') {
                res.push_back((++cnt)&1);
            } else {
                res.push_back((cnt--)&1);
            }
        }
        return res;
    }
};

python

class Solution:
    def maxDepthAfterSplit(self, seq: str) -> List[int]:
        cnt = 0
        res = []
        for c in seq:
            if c == '(':
                cnt += 1
                res.append(cnt&1)
            else:
                res.append(cnt&1)
                cnt -= 1
        return res

简化(c++)

class Solution {
public:
    vector<int> maxDepthAfterSplit(string seq) {
        vector<int> res;
        for (int i = 0, sz = seq.size(); i < sz; ++i) {
            res.push_back((i&1)^(seq[i]=='('));
        }
        return res;
    }
};

简化(python)

class Solution:
    def maxDepthAfterSplit(self, seq: str) -> List[int]:
        res = []
        for i, c in enumerate(seq):
            res.append((i&1)^(c=='('))
        return res
相关文章
|
弹性计算 Java 大数据
揭秘企业数据智能创新奥秘 | 2023云栖大会倚天专场
【倚天专场】邀请了弹性计算、操作系统、平头哥、ARM中国等专家为大家解读阿里云倚天ECS实例最新进展,包括云原生处理器最新技术、龙蜥+倚天软硬件结合、倚天ECS实例最佳实践等话题,为客户上云提供一个更具“性价比”的选择,加速企业数据智能创新。
|
7月前
|
人工智能 监控 数据可视化
Agent TARS:一键让AI托管电脑!字节开源PC端多模态AI助手,无缝集成浏览器与系统操作
Agent TARS 是一款开源的多模态AI助手,能够通过视觉解析网页并无缝集成命令行和文件系统,帮助用户高效完成复杂任务。
3550 13
Agent TARS:一键让AI托管电脑!字节开源PC端多模态AI助手,无缝集成浏览器与系统操作
|
运维 Kubernetes Cloud Native
云原生时代的容器编排:Kubernetes入门与实践
【10月更文挑战第4天】在云计算的浪潮中,云原生技术以其敏捷、可扩展和高效的特点引领着软件开发的新趋势。作为云原生生态中的关键组件,Kubernetes(通常被称为K8s)已成为容器编排的事实标准。本文将深入浅出地介绍Kubernetes的基本概念,并通过实际案例引导读者理解如何利用Kubernetes进行高效的容器管理和服务部署。无论你是初学者还是有一定经验的开发者,本文都将为你打开云原生世界的大门,并助你一臂之力在云原生时代乘风破浪。
|
11月前
|
Java Kotlin
Kotlin教程笔记(19) - 内部类
Kotlin教程笔记(19) - 内部类
|
编解码 安全
QQ远程协助显示对方桌面窗口倾斜解决方法 & 卸载Bonjour一法
QQ远程协助显示对方桌面窗口倾斜解决方法 & 卸载Bonjour一法
|
前端开发 JavaScript Go
前端开发规范
前端开发规范
11979 3
Argument 2 passed to think\\filesystem\\Driver::putFile() must be an instance of think\\File
Argument 2 passed to think\\filesystem\\Driver::putFile() must be an instance of think\\File
1275 0
|
JavaScript 前端开发
基于装饰器——我劝你不要在业务代码上装逼!!!(上)
基于装饰器——我劝你不要在业务代码上装逼!!!(上)
153 0
|
存储 Java 数据安全/隐私保护
Java经典笔试题—day07
Java经典笔试题—day07
147 0
|
Java Windows
JDK windows加载字体文件的函数
JDK windows加载字体文件的函数
161 0