2. <tag-栈和常规题>-lt.20. 有效的括号 + lt.1047. 删除字符串中的所有相邻重复项
lt.20. 有效的括号
[案例需求]

[思路分析一, 栈的使用]
用栈存储左括号, 然后当遇到右括号时, 当栈不为空时, 出栈一个元素, 如果不是互相搭配的左右括号时, 立刻返回true;
如果遇到右括号, 而栈此时已经是空栈了, 那肯定要返回 false;
最终整个符号的char数组遍历完毕, 只需要要返回对栈是否为空的判断结果即可;
[代码实现]
class Solution {
public boolean isValid(String s) {
//左括号入栈, 遇到右括号出栈
char[] chars = s.toCharArray();
Stack<Character> st = new Stack<>();
for(char ch : chars){
//左括号
if(ch == '(' || ch == '[' || ch == '{'){
st.push(ch);
}else{
if(!st.isEmpty()){
if(ch == ')'){
if(st.pop() != '(')return false;
}else if(ch == ']'){
if(st.pop() != '[')return false;
}else{
if(st.pop() != '{')return false;
}
}else{
return false;
}
}
}
return st.isEmpty();
}
}
[思路分析二, 栈和哈希表的使用]
[代码示例]
class Solution {
public boolean isValid(String s) {
//首先,判断s长度若为奇数,则一定不成对,返回false
int n = s.length();
if(n%2 == 1)
return false;
//定义一个辅助栈,判断')'在s中是否有对应的'('
Map<Character,Character> pairs = new HashMap<Character,Character>(){{
put(')','(');
put(']','[');
put('}','{');
}};
//定义栈
Deque<Character> stack = new LinkedList<Character>();
for(int i=0;i<s.length();i++){
//获取s的第i个字符
char ch =s.charAt(i);
//判断ch是否为右括号
if(pairs.containsKey(ch)){
//判断栈是否为空或者栈顶元素是否等于ch的value,若满足其中一个则返回false
//若栈为空则表示,右括号在做左括号前面;若栈顶元素和ch的value不相等,则不匹配
if(stack.isEmpty() || stack.peek()!=pairs.get(ch)){
return false;
}
stack.pop();
}else{
stack.push(ch);
}
}
return stack.isEmpty();
}
}
lt.1047. 删除字符串中的所有相邻重复项
[案例需求]

[思路分析一, 学弱解法(栈存储, 再转化为String)]
充分理解题意后,我们可以发现,当字符串中同时有多组相邻重复项时,我们无论是先删除哪一个,都不会影响最终的结果。因此我们可以从左向右顺次处理该字符串。
而消除一对相邻重复项可能会导致新的相邻重复项出现,如从字符串 abba 中删除 bb会导致出现新的相邻重复项 aa出现。因此我们需要保存当前还未被删除的字符。
- 一种显而易见的数据结构呼之欲出:栈。我们只需要遍历该字符串,如果当前字符和栈顶字符相同,我们就贪心地将其消去,否则就将其入栈即可。
代码
在C++代码中,由于std::string类本身就提供了类似「入栈」和「出栈」的接口,因此我们直接将需要被返回的字符串作为栈即可。对于其他的语言,如果字符串类没有提供相应的接口,则需要在遍历完成字符串后,使用栈中的字符显式地构造出需要被返回的字符串。
[代码实现]
class Solution {
public String removeDuplicates(String s) {
char[] chars = s.toCharArray();
Stack<Character> st = new Stack<>();
st.push(chars[0]);
for(int i = 1; i < chars.length; i++){
if(!st.isEmpty() && st.peek() == chars[i]){
st.pop();
continue;
}else{
st.push(chars[i]);
}
}
//stack -> string ?
// StringBuilder sb = new StringBuilder();
// while(!st.isEmpty()){
// sb.append(st.pop());
// }
char[] res = new char[st.size()];
int index = st.size() - 1;
while(!st.isEmpty()){
res[index--] = st.pop();
}
return String.valueOf(res);
}
}
[思路分析二, 用StringBuilder作为栈]
[代码实现]
class Solution {
public String removeDuplicates(String s) {
StringBuilder stack = new StringBuilder();
int top = -1;
for (int i = 0; i < s.length(); ++i) {
char ch = s.charAt(i);
if (top >= 0 && stack.charAt(top) == ch) {
stack.deleteCharAt(top);
--top;
} else {
stack.append(ch);
++top;
}
}
return stack.toString();
}
}
[思路分析三, 用数组作为栈]
[代码实现]
//1. 用数组作为栈
class Solution {
public String removeDuplicates(String S) {
char[] s = S.toCharArray();
int top = -1;
for (int i = 0; i < S.length(); i++) {
if (top == -1 || s[top] != s[i]) {
s[++top] = s[i];
} else {
top--;
}
}
return String.valueOf(s, 0, top + 1);
}
}


浙公网安备 33010602011771号