leetcode每日一题:使字符串平衡的最小交换次数

引言
今天开始,打算做一个新的系列:leetcode每日一题的题解。预期每天用90分钟的时间,去写一篇当天的每日一题的题解,这个目标跟早起结合在一起,才有足够的时间完成。其实早在前几年,就开始断断续续做leetcode的每日一题,但每次连续坚持的时间都不长,可能坚持一个多月,就因为各种原因间断了。一鼓作气,再而衰,三而竭。这种需要长期坚持的事情,一旦间断,就很难再继续坚持了。今天选择再出发,先给自己定个小目标:至少坚持100天。
题目
给你一个字符串 s ,下标从 0 开始 ,且长度为偶数 n 。字符串 恰好 由 n / 2 个开括号 '[' 和 n / 2 个闭括号 ']' 组成。
只有能满足下述所有条件的字符串才能称为 平衡字符串 :
- 字符串是一个空字符串,或者
- 字符串可以记作
AB,其中A和B都是 平衡字符串 ,或者 - 字符串可以写成
[C],其中C是一个 平衡字符串 。
你可以交换 任意 两个下标所对应的括号 任意 次数。
返回使 s 变成 平衡字符串 所需要的 最小 交换次数。
示例 1:
输入:s = "][]["
输出:1
解释:交换下标 0 和下标 3 对应的括号,可以使字符串变成平衡字符串。
最终字符串变成 "[[]]" 。
示例 2:
输入:s = "]]][[["
输出:2
解释:执行下述操作可以使字符串变成平衡字符串:
- 交换下标 0 和下标 4 对应的括号,s = "[]][][" 。
- 交换下标 1 和下标 5 对应的括号,s = "[[][]]" 。
最终字符串变成 "[[][]]" 。
示例 3:
输入:s = "[]"
输出:0
解释:这个字符串已经是平衡字符串。
提示:
n == s.length2 <= n <= 106n为偶数s[i]为'['或']'- 开括号
'['的数目为n / 2,闭括号']'的数目也是n / 2
思路
题目中描述的“平衡字符串”,其实可以用一句话来概括:合法的括号。即对于每个右括号而言,都可以在它的左侧找到唯一的一个只匹配给它的左括号。
栈
提到合法的括号,很多同学第一反应就是栈。我们在判断一个字符串是否是合法的括号,就是栈的做法:
- 遇到左括号,压栈
- 遇到右括号,出栈,如果栈为空,那么此时肯定不是合法的括号
不过本题有一些差异,并不是要判断这个字符串是不是合法的括号,而是要求出,最小交换几对,使得这个字符串变成合法的括号。所以,我们这里处理上,也有一些小差异:可以把压栈和出栈的操作看到最合法括号的对消,类似消消乐,那么当我们遇到当前是右括号且空栈的情况下,没有左侧括号可以匹配,可以把这个单独的右括号记录下来。由于整体来看,左右括号的数量必然是相等的,所以我们把合法的括号都消除后,留下来的必然是这样的形式:“]]]...[[[”,k个']'开头,后面跟着k个‘[’。不难想到,我们拿最前面的(k+1)/2个右括号‘]’去跟最后面的(k+1)/2个左括号‘[’交换后,整个字符串就是合法的括号了。
图解

代码

public int minSwaps0(String s) {
int right = 0;
Stack<Character> stack = new Stack<>();
for (char c : s.toCharArray()) {
if (c == '[') {
stack.push(c);
} else if (c == ']') {
if (!stack.isEmpty()) {
stack.pop();
} else {
right++;
}
}
}
return (right + 1) >> 1;
}
注意:这里最后使用了xxx >> 1这样的位移操作来代替除以2的操作,是对于整数 乘以2 或者 除以2 运算的常见优化,提高执行效率。
耗时

优化
进一步想,我们这里其实并不需要真正操作压栈和出栈,直接用一个整形变量cnt代替,压栈操作转换为+1,出栈操作转换为-1,判断栈是否为空可以转换为cnt == 0。
代码

public int minSwaps(String s) {
int right = 0;
int cnt = 0;
for (char c : s.toCharArray()) {
if (c == '[') {
cnt++;
} else if (c == ']') {
if (cnt != 0) {
cnt--;
} else {
right++;
}
}
}
return (right + 1) >> 1;
}
耗时

leetcode每日一题:使字符串平衡的最小交换次数的更多相关文章
- 【python】Leetcode每日一题-扰乱字符串
[python]Leetcode每日一题-扰乱字符串 [题目描述] 使用下面描述的算法可以扰乱字符串 s 得到字符串 t : 如果字符串的长度为 1 ,算法停止 如果字符串的长度 > 1 ,执行 ...
- Java实现 LeetCode 801 使序列递增的最小交换次数 (DP)
801. 使序列递增的最小交换次数 我们有两个长度相等且不为空的整型数组 A 和 B . 我们可以交换 A[i] 和 B[i] 的元素.注意这两个元素在各自的序列中应该处于相同的位置. 在交换过一些元 ...
- [Swift]LeetCode801. 使序列递增的最小交换次数 | Minimum Swaps To Make Sequences Increasing
We have two integer sequences A and B of the same non-zero length. We are allowed to swap elements A ...
- 【python】Leetcode每日一题-最大数
[python]Leetcode每日一题-最大数 [题目描述] 给定一组非负整数 nums,重新排列每个数的顺序(每个数不可拆分)使之组成一个最大的整数. 注意:输出结果可能非常大,所以你需要返回一个 ...
- 【js】Leetcode每日一题-完成所有工作的最短时间
[js]Leetcode每日一题-完成所有工作的最短时间 [题目描述] 给你一个整数数组 jobs ,其中 jobs[i] 是完成第 i 项工作要花费的时间. 请你将这些工作分配给 k 位工人.所有工 ...
- 【JavaScript】Leetcode每日一题-递增顺序搜索树
[JavaScript]Leetcode每日一题-递增顺序搜索树 [题目描述] 给你一棵二叉搜索树,请你 按中序遍历 将其重新排列为一棵递增顺序搜索树,使树中最左边的节点成为树的根节点,并且每个节点没 ...
- 【JavaScript】【dp】Leetcode每日一题-解码方法
[JavaScript]Leetcode每日一题-解码方法 [题目描述] 一条包含字母 A-Z 的消息通过以下映射进行了 编码 : 'A' -> 1 'B' -> 2 ... 'Z' -& ...
- 【JavaScript】【KMP】Leetcode每日一题-实现strStr()
[JavaScript]Leetcode每日一题-实现strStr() [题目描述] 实现 strStr() 函数. 给你两个字符串 haystack 和 needle ,请你在 haystack 字 ...
- 【python】Leetcode每日一题-删除有序数组中的重复项
[python]Leetcode每日一题-删除有序数组中的重复项 [题目描述] 给你一个有序数组 nums ,请你 原地 删除重复出现的元素,使每个元素 最多出现一次 ,返回删除后数组的新长度. 不要 ...
- [LeetCode每日一题]81. 搜索旋转排序数组 II
[LeetCode每日一题]81. 搜索旋转排序数组 II 问题 已知存在一个按非降序排列的整数数组 nums ,数组中的值不必互不相同. 在传递给函数之前,nums 在预先未知的某个下标 k(0 & ...
随机推荐
- biancheng-linux-shell
参考http://c.biancheng.net/view/706.html Shell变量:Shell变量的定义.赋值和删除 Shell 支持以下三种定义变量的方式: variable=valuev ...
- canal源码分析简介-1
1.0 canal源码分析简介 canal是阿里巴巴开源的mysql数据库binlog的增量订阅&消费组件.项目github地址为:https://github.com/alibaba/can ...
- .net工作流elsa-书签
啥是书签 流程引擎的核心关注点是安排流程,如:第1步做什么 → 第2步做什么 → 第n步做什么...,至于各步骤具体是怎么做的,是由你来决定的,这不是流程引擎关注的重点. 流程安排可能会涉及到分叉.并 ...
- 基础《Go学习笔记》读书笔记——函数
writer:zgx lastmodify:2020年09月26日 目录 第四章--函数 变参 返回值 匿名函数 闭包 延迟调用 误用 性能 错误处理 error panic, recover Dra ...
- 记一次 .NET某数字化协同管理系统 内存暴涨分析
一:背景 1. 讲故事 高级调试训练营里的一位朋友找到我,说他们跑在linux上的.NET程序出现了内存泄露的情况,上windbg观察发现内存都是IMAGE给吃掉了,那些image都标记了 doubl ...
- 虚拟机设置静态IP并启用桥接模式
虚拟机设置静态IP并启用桥接模式 一.准备工作 在开始之前,请确保你已经安装了VMware或其他虚拟机软件,并且已经创建了一个虚拟机实例. 此外,还需要了解宿主机的网络配置,包括IP地址.子网掩码.网 ...
- [业界方案] Yarn的业界解决方案和未来方向
[业界方案] Yarn的业界解决方案和未来方向 目录 [业界方案] Yarn的业界解决方案和未来方向 0x00 摘要 0x01 Yarn 1.1 参考文章 0x02 分析 2.1 综述 2.1.1 y ...
- Romberg 数值积分算法+P3779 题解
Romberg 算法 吊打 Simpson(?) 的且不玄学(没有什么十五倍)的数值积分算法. 缺点是过程复杂一点,但是只体现在证明上,代码很短. 铺垫算法 梯形求积公式 公式 \[\int _a^b ...
- Maven配置多仓库
一.配置说明 <?xml version="1.0" encoding="UTF-8"?> <settings xmlns="htt ...
- 流程控制之break、continue和goto
#### 实例1: ```javapackage com.yeyue.struct; public class BreakDemo { public static void main(String[] ...