题目

一个括号字符串是只由 '('')' 组成的 非空 字符串。如果一个字符串满足下面 任意 一个条件,那么它就是有效的:

  • 字符串为 ().
  • 它可以表示为 ABAB 连接),其中AB 都是有效括号字符串。
  • 它可以表示为 (A) ,其中 A 是一个有效括号字符串。

给你一个括号字符串 s 和一个字符串 locked ,两者长度都为 nlocked 是一个二进制字符串,只包含 '0''1' 。对于 locked每一个 下标 i

  • 如果 locked[i]'1' ,你 不能 改变 s[i]
  • 如果 locked[i]'0' ,你 可以s[i] 变为 '(' 或者 ')'

如果你可以将 s 变为有效括号字符串,请你返回 true ,否则返回 false

示例 1:

输入:s = "))()))", locked = "010100"
输出:true
解释:locked[1] == '1' 和 locked[3] == '1' ,所以我们无法改变 s[1] 或者 s[3] 。
我们可以将 s[0] 和 s[4] 变为 '(' ,不改变 s[2] 和 s[5] ,使 s 变为有效字符串。

示例 2:

输入:s = "()()", locked = "0000"
输出:true
解释:我们不需要做任何改变,因为 s 已经是有效字符串了。

示例 3:

输入:s = ")", locked = "0"
输出:false
解释:locked 允许改变 s[0] 。
但无论将 s[0] 变为 '(' 或者 ')' 都无法使 s 变为有效字符串。

示例 4:

输入:s = "(((())(((())", locked = "111111010111"
输出:true
解释:locked 允许我们改变 s[6] 和 s[8]。
我们将 s[6] 和 s[8] 改为 ')' 使 s 变为有效字符串。

提示:

  • n == s.length == locked.length
  • 1 <= n <= 105
  • s[i] 要么是 '(' 要么是 ')'
  • locked[i] 要么是 '0' 要么是 '1'

思路

​ 一看到题目是判断合法括号,就想到了这题好像我会啊,不就是用栈来判断,左括号压栈,右括号出栈,如果栈最后为空,且中间也没有不够用(遇到右括号,但是栈为空导致无元素可以弹出),那么就是合法括号。

​ 如果只有一种括号,这里还可以优化,不需要真正去压栈和出栈,用一个变量,左括号就+1,右括号就-1,直到最后结果为0,且中间不存在任何时候是小于0的情况,就是合法括号。

​ 本题略微有一些变化,求的是是否可以通过改变原始字符串,变成合法括号。一个合法的括号,必然满足如下条件:

  • 长度为偶数,其中一半是左括号,一半是右括号
  • 任意一个前缀,都满足左括号数量大于等于右括号数量
  • 任意一个后缀,都满足右括号数量大于等于左括号数量

​ 只有locked为1的位置,原始括号才不可变,其他位置的原始括号是可变的,即不用管原始括号是什么。具体操作上,我们可以做如下3步校验:

  • 长度为偶数,如果为奇数,肯定不是合法的
  • 对于任意一个前缀,贪心的认为,任何非locked的位置,都变成左括号的情况下,都满足左括号数量大于等于右括号数量
  • 对于任意一个后缀,贪心的认为,任何非locked的位置,都变成右括号的情况下,都满足右号数量大于等于左括号数量

代码

public boolean canBeValid(String s, String locked) {
// 长度为奇数,不可能是合法括号
int n = s.length();
if ((n & 1) == 1) {
return false;
}
char[] chars = s.toCharArray();
char[] lockedChars = locked.toCharArray();
// 任意一个前缀,左括号都大于等于右括号
int left = 0;
for (int i = 0; i < n; i++) {
if (lockedChars[i] == '1' && chars[i] == ')') {
left--;
} else {
left++;
}
if (left < 0) {
return false;
}
}
// 任意一个后缀,右括号都大于等于左括号
int right = 0;
for (int i = n - 1; i >= 0; i--) {
if (lockedChars[i] == '1' && chars[i] == '(') {
right--;
} else {
right++;
}
if (right < 0) {
return false;
}
}
return true;
}

耗时

leetcode每日一题:判断一个括号字符串是否有效的更多相关文章

  1. 【python】Leetcode每日一题-扰乱字符串

    [python]Leetcode每日一题-扰乱字符串 [题目描述] 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行 ...

  2. LeetCode 每日一题「判定字符是否唯一」

    我是陈皮,一个在互联网 Coding 的 ITer,微信搜索「陈皮的JavaLib」第一时间阅读最新文章,回复[资料],即可获得我精心整理的技术资料,电子书籍,一线大厂面试资料和优秀简历模板. 题目 ...

  3. 【JavaScript】Leetcode每日一题-平方数之和

    [JavaScript]Leetcode每日一题-平方数之和 [题目描述] 给定一个非负整数 c ,你要判断是否存在两个整数 a 和 b,使得 a2 + b2 = c . 示例1: 输入:c = 5 ...

  4. 【JavaScript】【dp】Leetcode每日一题-解码方法

    [JavaScript]Leetcode每日一题-解码方法 [题目描述] 一条包含字母 A-Z 的消息通过以下映射进行了 编码 : 'A' -> 1 'B' -> 2 ... 'Z' -& ...

  5. 【JavaScript】【KMP】Leetcode每日一题-实现strStr()

    [JavaScript]Leetcode每日一题-实现strStr() [题目描述] 实现 strStr() 函数. 给你两个字符串 haystack 和 needle ,请你在 haystack 字 ...

  6. [LeetCode每日一题]81. 搜索旋转排序数组 II

    [LeetCode每日一题]81. 搜索旋转排序数组 II 问题 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同. 在传递给函数之前,nums 在预先未知的某个下标 k(0 & ...

  7. 【python】Leetcode每日一题-存在重复元素3

    [python]Leetcode每日一题-存在重复元素3 [题目描述] 给你一个整数数组 nums 和两个整数 k 和 t .请你判断是否存在 两个不同下标 i 和 j,使得 abs(nums[i] ...

  8. 【python】Leetcode每日一题-最大数

    [python]Leetcode每日一题-最大数 [题目描述] 给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数. 注意:输出结果可能非常大,所以你需要返回一个 ...

  9. 【python】Leetcode每日一题-丑数

    [python]Leetcode每日一题-丑数 [题目描述] 给你一个整数 n ,请你判断 n 是否为 丑数 .如果是,返回 true :否则,返回 false . 丑数 就是只包含质因数 2.3 和 ...

  10. 【python】Leetcode每日一题-最长公共子序列

    [python]Leetcode每日一题-最长公共子序列 [题目描述] 给定两个字符串 text1 和 text2,返回这两个字符串的最长 公共子序列 的长度.如果不存在 公共子序列 ,返回 0 . ...

随机推荐

  1. VBA 解析 json

    Sub Macro1() Debug.Print "999" Dim FilePath, strData FilePath = "C:\Git\Test\JenProje ...

  2. JAVA多线程和并发性知识点总结

    一. 什么是进程.线程?线程和进程的区别?1. 进程当一个程序进入内存运行时,即变成一个进程.进程是处于运行过程中的程序.进程是操作系统进行资源分配和调度的一个独立单位.进程的三个特征: 独立性独立存 ...

  3. 从单体架构、到SOA、再到微服务的架构设计详解

    本文涉及的内容以及知识点如下: 1.单体架构 2.单体架构的拆分 3.SOA与微服务的区别 4.微服务的优缺点 5.微服务的消息 6.服务集成 7.数据的去中心化 单体架构 Web应用程序发展的早期, ...

  4. 使用Python的一维卷积

    学习&转载文章:使用Python的一维卷积 背景 在开发机器学习算法时,最重要的事情之一(如果不是最重要的话)是提取最相关的特征,这是在项目的特征工程部分中完成的. 在CNNs中,此过程由网络 ...

  5. MySQL系统命令

    原文链接:https://blog.liuzijian.com/post/34b3b940-c053-9d75-06e2-07a2e7aeedc3.html 登录命令 mysql -h 主机 -P 端 ...

  6. 面试题: == 和 equals() 区别【包装类重写了object类中的equals方法】

    /* * * 面试题: == 和 equals() 区别 * * 一.回顾 == 的使用: * == :运算符 * 1. 可以使用在基本数据类型变量和引用数据类型变量中 * 2. 如果比较的是基本数据 ...

  7. [BZOJ P2771] 天才ACM

    [BZOJ P2771] 天才ACM 传送门 朴素算法 枚举终点 \(r\),对区间 \([l, r]\) 排序求校验值 \(sum\),比较 \(sum\) 和 \(t\) $ sum \le t ...

  8. uni-app使用阿里矢量字体图标

    在app.vue下,引入 <style> @font-face { font-family: 'iconfont'; /* project id 1951514 */ src: url(' ...

  9. 手把手教你在本地部署DeepSeek R1,搭建web-ui ,建议收藏!

    写在前面 最近,DeepSeek 发布的推理大模型 DeepSeek - R1 ,可以说是AI大模型领域杀出的一匹黑马.它在国外大模型排名 Arena 上成绩惊人,基准测试位列全类别大模型第三,在风格 ...

  10. Linux7安装pacemaker+corosync集群-02--配置集群文件系统gfs2(dlm+clvmd)

    配置集群文件系统: 安装软件包: yum -y install   lvm2* gfs2* dlm* 1.安装rpm包 yum -y install   lvm2* gfs2* dlm* fence- ...