文章:代码随想录
总结:栈在连续,相邻的位置做匹配/消除/运算的场景很适用.
leecode 20 有效括号
思路:
做这道题之前有一些特性需要明白,括号是符合先进后出的原理的,也就是后进先出. 比如({[]}),先进入的(肯定是包含在最外面的,最后进入的左[括号一定是最先出现右括号的,所以是先进后出。 那么很显然就可以用栈来实现这个问题。
public boolean isValid(String s) {
//如果s的长度为奇数,那肯定是不符合要求的,因为括号成双成对出现
if(s.length()%2!=0){return false;}
Stack<Character> rightParentheses=new Stack<>();
for (int i = 0; i < s.length(); i++) {
char ch=s.charAt(i);
//遇到左括号,压入右括号
if(ch=='('){rightParentheses.push(')');}
else if (ch=='{'){rightParentheses.push('}');}
else if(ch=='['){rightParentheses.push(']');}
//走到这里说明输入的是右括号,如果栈空了说明存在右括号多余的情况。如果不匹配则证明发生了左右括号不匹配的情况,都直接返回false.
else if(rightParentheses.empty() || ch!=rightParentheses.peek()){return false;}
//相同情况
else {rightParentheses.pop();}
}
//结束时要判断是否全部弹出,因为如果左括号或者又括号多余上面的循环是无法返回false的.
return rightParentheses.empty();
}
leecode 1047 删除字符串中相邻的重复项
思路:和找有效括号的思路是一样的,因为找有效括号有一部分逻辑也是相当于消除相邻的重复括号,所以这道题的代码会更精简。 用栈是显而易见的,那么其实这里可以用一个字符串模拟栈的行为,这样就不用最后再通过栈里的元素来转换成字符串。 //然后我们还可以将这个字符串的头尾转换,这样最后也不用倒序输出。
代码:
public String removeDuplicates(String s) {
StringBuilder result = new StringBuilder();
for (int i = 0; i < s.length(); i++) {
//不相等就push
if (result.isEmpty() || s.charAt(i) != result.charAt(result.length() - 1)) {
result.append(s.charAt(i));
}else {
//元素相等的情况就移除栈内元素.(pop)
result.deleteCharAt(result.length()-1);
}
}
return result.toString();
}
//操作更快的charArray方式
public String removeDuplicatesCharArray(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);
}
leecode 150 逆波兰式
思路:
遇到元素压入栈中,算术表达式就将栈的头两个元素拿出来计算再把计算完的值压入栈中。 //要注意顺序式是头元素中的后一个与第一个运算,比如是后一个除以第一个,减去第一个等等.
代码:
public int evalRPN(String[] tokens) {
Stack<Integer> result=new Stack<>();
for (String s:tokens) {
if(s.equals("+")){
result.push(result.pop()+result.pop());
}else if(s.equals("-")){
result.push(-result.pop()+result.pop());
}else if(s.equals("*")){
result.push(result.pop()*result.pop());
}else if(s.equals("/")){
int result1=result.pop();
int result2=result.pop();
result.push(result2/result1);
}else {
result.push(Integer.valueOf(s));
}
}
return result.pop();
}
//数组模拟栈的方法
public int evalRPNArray(String[] tokens) {
int n = tokens.length;
int[] stack = new int[(n + 1) / 2];
int index = -1;
for (int i = 0; i < n; i++) {
String token = tokens[i];
switch (token) {
case "+":
index--;
stack[index] += stack[index + 1];
break;
case "-":
index--;
stack[index] -= stack[index + 1];
break;
case "*":
index--;
stack[index] *= stack[index + 1];
break;
case "/":
index--;
stack[index] /= stack[index + 1];
break;
default:
index++;
stack[index] = Integer.parseInt(token);
}
}
return stack[index];
}