有效的括号
思路
先分析有几种不匹配的情况
1.字符串里左括号多余
2.类型不匹配
3.右括号多余
第一种情况:已经遍历完了字符串,但是栈不为空,说明左括号没有右括号来匹配,false
第二种情况:白能力字符串,发现栈里没有要匹配的字符,false
第三种情况:遍历字符串匹配的时候,栈已经空了,没有匹配的字符,说明右括号没有对应的左括号,false
代码
class Solution {
public boolean isValid(String s) {
Deque<Character> deque = new LinkedList<>();
char ch;
for (int i = 0; i < s.length(); i++) {
ch = s.charAt(i);
//碰到左括号,就把相应的右括号入栈
if (ch == '(') {
deque.push(')');
}else if (ch == '{') {
deque.push('}');
}else if (ch == '[') {
deque.push(']');
} else if (deque.isEmpty() || deque.peek() != ch) {
return false;
}else {//如果是右括号判断是否和栈顶元素匹配
deque.pop();
}
}
//最后判断栈中元素是否匹配
return deque.isEmpty();
}
}
删除字符串中的所有相邻重复项
思路
跟上一个题一样,遍历一遍字符串中的元素,遍历过的元素用栈来存放,遍历一个元素,找一下栈里有没有一样的元素,有就弹出,没有就留着。最后把栈转化成字符串输出。
代码
class Solution {
public String removeDuplicates(String S) {
//ArrayDeque会比LinkedList在除了删除元素这一点外会快一点
//参考:https://stackoverflow.com/questions/6163166/why-is-arraydeque-better-than-linkedlist
ArrayDeque<Character> deque = new ArrayDeque<>();
char ch;
for (int i = 0; i < S.length(); i++) {
ch = S.charAt(i);
if (deque.isEmpty() || deque.peek() != ch) {
deque.push(ch);
} else {
deque.pop();
}
}
String str = "";
//剩余的元素即为不重复的元素
while (!deque.isEmpty()) {
str = deque.pop() + str;
}
return str;
}
}
逆波兰表达式求值
思路
首先逆波兰表达式是把运算符放在后面的表达式,更适合计算机的逻辑方式。读取到数字就入栈,读取到运算符就取出栈内两个数字进行运算,把运算完的数字再放进栈内,栈内最后剩的数字为最后的答案。
代码
class Solution {
public int evalRPN(String[] tokens) {
Deque<Integer> stack = new LinkedList();
for (String s : tokens) {
if ("+".equals(s)) { // leetcode 内置jdk的问题,不能使用==判断字符串是否相等
stack.push(stack.pop() + stack.pop()); // 注意 - 和/ 需要特殊处理
} else if ("-".equals(s)) {
stack.push(-stack.pop() + stack.pop());
} else if ("*".equals(s)) {
stack.push(stack.pop() * stack.pop());
} else if ("/".equals(s)) {
int temp1 = stack.pop();
int temp2 = stack.pop();
stack.push(temp2 / temp1);
} else {
stack.push(Integer.valueOf(s));
}
}
return stack.pop();
}
}