一、前言
主要是因为这道题我没看评论和题解,并且我觉得自己的解法挺有趣,java代码的时间上击败100%,所以想记录一下。
ps:对于用单调栈解的那些题目也很有趣,不过笔记记在本地上了。
二、题目
网址:https://leetcode-cn.com/problems/minimum-remove-to-make-valid-parentheses/
三、解题思路
注意:
- 在这一道题中,用于模拟栈和接收字符的数组都是同一个。
- 栈底是数组中索引为 s.length()-1 的位置。接收字符则从字符数组索引为0的位置开始接收。
- 对于这一个字符数组,前面部分充当接收字符的字符数组,后面部分充当栈,它们不会互相覆盖,因为是先出栈,再接收。
步骤:
- 用一个变量记录r右括号数量。
- 首先逆序遍历s:
- 遇到左括号,如果r为0,则不入栈,否则入栈并且r-1;
- 遇到右括号直接入栈,r+1;
- 其它字符直接入栈。
- 结束遍历s后,开始出栈,当栈顶非空的时候:
- 如果r大于0且当前出栈的元素为右括号,则抛弃这一出栈的元素,并且r-1;
- 否则接收这一字符。
- 返回这一字符串。
四、代码
java代码:
public String minRemoveToMakeValid(String s) {
// 先是从右边开始入栈
// 右括号数量
int rightBracketsCount = 0;
// 模拟栈
int top = s.length();
char[] stack = new char[s.length()];
// 遍历
char ch;
int index = top;
while (index > 0) {
ch = s.charAt(--index);
if (ch == '(') {
if (rightBracketsCount == 0) {
// 如果匹配完就不入栈了
continue;
}
// 如果右边有'('没匹配完
rightBracketsCount--;
} else if (ch == ')') {
rightBracketsCount++;
}
// 入栈
stack[--top] = ch;
}
// 此时还有右括号没有匹配完, 那么就从栈顶top开始匹配
while (top < s.length()) {
ch = stack[top++];
if (rightBracketsCount > 0 && ch == ')') {
rightBracketsCount--;
continue;
}
stack[index++] = ch;
}
return new String(stack, 0, index);
}