有效的括号字符串
难度:
标签:
题目描述
代码结果
运行时间: 22 ms, 内存: 15.9 MB
/*
* 题目思路:
* 使用 Java Stream 实现有效字符串的判断。
* 我们可以用两个变量来追踪未匹配的左括号数量,
* 并利用 Stream API 遍历字符,更新计数器的值。
* 最后判断最低的未匹配左括号数量是否为 0。
*/
import java.util.stream.Stream;
public class Solution {
public boolean checkValidString(String s) {
int[] counts = new int[2]; // counts[0] 是 minOpen, counts[1] 是 maxOpen
s.chars().forEach(c -> {
if (c == '(') {
counts[0]++;
counts[1]++;
} else if (c == ')') {
counts[0] = Math.max(counts[0] - 1, 0);
counts[1]--;
} else { // c == '*'
counts[0] = Math.max(counts[0] - 1, 0);
counts[1]++;
}
});
return counts[0] == 0;
}
}
解释
方法:
这个题解使用两个栈 l 和 sign 分别存储左括号 '(' 和星号 '*' 的下标。遍历字符串,遇到左括号入栈 l,遇到星号入栈 sign,遇到右括号则优先弹出 l 栈顶元素,若 l 为空则弹出 sign 栈顶元素,若 sign 也为空说明没有左括号与当前右括号匹配,返回 false。最后从 l 和 sign 的栈顶开始比较下标,若 l 栈顶元素下标大于 sign 栈顶元素的下标,说明无法匹配,返回 false。若最终 l 栈为空则说明所有的左括号都被匹配,字符串有效,返回 true。
时间复杂度:
O(n)
空间复杂度:
O(n)
代码细节讲解
🦆
为什么在处理右括号时,优先选择弹出存储左括号的栈`l`而不是星号栈`sign`?
▷🦆
如果在遍历结束后,`sign`栈中的星号下标全都小于`l`栈中的左括号下标,这种情况下算法是否还能正确处理,返回正确的结果?
▷🦆
在最后的栈下标比较过程中,如果`sign`栈为空但`l`栈还有剩余元素,这种情况下的处理逻辑是什么?
▷🦆
算法在处理星号时将其下标直接存入`sign`栈,这是否意味着所有的星号都被默认先当作右括号处理?如果不是,这种处理方式如何确保星号的多重可能性被正确考虑?
▷相关问题
特殊的二进制序列
特殊的二进制序列是具有以下两个性质的二进制序列:
- 0 的数量与 1 的数量相等。
- 二进制序列的每一个前缀码中 1 的数量要大于等于 0 的数量。
给定一个特殊的二进制序列 S
,以字符串形式表示。定义一个操作 为首先选择 S
的两个连续且非空的特殊的子串,然后将它们交换。(两个子串为连续的当且仅当第一个子串的最后一个字符恰好为第二个子串的第一个字符的前一个字符。)
在任意次数的操作之后,交换后的字符串按照字典序排列的最大的结果是什么?
示例 1:
输入: S = "11011000" 输出: "11100100" 解释: 将子串 "10" (在S[1]出现) 和 "1100" (在S[3]出现)进行交换。 这是在进行若干次操作后按字典序排列最大的结果。
说明:
S
的长度不超过50
。S
保证为一个满足上述定义的特殊 的二进制序列。