20. 有效的括号
思路:
-
考虑略微复杂的情况 ——
([{}]),主体思路是只要是左括号(无论是哪种类型的左括号)都将其入栈,一旦遇到右括号,将当前栈顶元素与之比较,如果能够匹配,则stack.pop() 注: 右括号永远不入栈。 -
题目中已经说了只会出现
(){}[]这三种括号,所以使用Map将其对应关系记录下来。
具体代码如下:
class Solution {
public boolean isValid(String s) {
Map<Character,Character> map=new HashMap<>();
map.put('(',')');
map.put('[',']');
map.put('{','}');
//将字符串转换为字符数组
char[] ch=s.toCharArray();
int len=ch.length;
//如果长度不是偶数 那么肯定没有办法完成匹配
if(len%2!=0){
return false;
}
Stack<Character> stack=new Stack<>();
for(int i=0;i<len;i++){
//如果是左括号,就入栈
if(ch[i]=='(' || ch[i]=='{' || ch[i]=='['){
stack.push(ch[i]);
}
//如果是右括号,不入栈,执行判断
else{
//如果当前是右括号。1、栈为空,没法匹配,返回false. 2、栈不为空但是匹配失败,return false;
if(stack.isEmpty() || ch[i]!=map.get(stack.pop())){
return false;
}
else{
continue;
}
}
}
//理论上如果均一 一匹配上,栈应当为空栈。
if(stack.isEmpty())
return true;
else
return false;
}
}
1047. 删除字符串中的所有相邻重复项
class Solution {
public String removeDuplicates(String s) {
Stack<Character> stack=new Stack<>();
int size=s.length();
for(int i=0;i<size;i++){
//如果栈为空 或者是 当前元素不等于栈顶元素 则入栈
if(stack.isEmpty() || s.charAt(i)!=stack.peek()){
stack.push(s.charAt(i));
continue;
}
//如果当前元素与栈顶元素重复,则直接把栈顶元素弹出
if(s.charAt(i)==stack.peek()){
stack.pop();
}
}
String result="";
while(!stack.isEmpty()){
result=stack.pop()+result;
}
return result;
}
}
栈的经典应用。
看了卡哥提示的代码之后,得到启发,不额外启用栈, 而是直接拿字符串作为栈。
class Solution {
public String removeDuplicates(String s) {
//使用StringBuilder来模拟栈
StringBuilder result=new StringBuilder();
//topIndex始终指向“栈顶”元素
int topIndex=-1;
int len=s.length();
for(int i=0;i<len;i++){
//如果result为空 或者是 当前元素与“栈顶”元素不相等 入栈
if(topIndex<0 || s.charAt(i)!=result.charAt(topIndex)){
result.append(s.charAt(i));
topIndex++;
}
//当前元素与“栈顶”元素相等
else{
result.deleteCharAt(topIndex);
topIndex--;
}
}
return result.toString();
}
}
150. 逆波兰表达式求值
这道题需要了解逆波兰表达式的求解规则,了解之后便不难。
唯一有一个点需要注意:
-
如果当前的元素是减号运算符的话,那么int num1=stack.pop(); int num2=stack.pop(); 减法操作是num2-num1 。 除法同理。
- 或者说无论是加减乘除 ,都是num2-num1
-
同时也需要知道,如果要将"12" 或者是 "-11" 转换成整型数字,那么就使用Integer.parseInt()方法,完成转换
class Solution {
public int evalRPN(String[] tokens) {
//模拟逆波兰的计算 实际上最重要的就是对栈的操作
int len=tokens.length;
Stack<Integer> stack=new Stack<>();
for(int i=0;i<len;i++){
//只要不是运算符 就入栈
if(!tokens[i].equals("+") && !tokens[i].equals("-") && !tokens[i].equals("*") && !tokens[i].equals("/")){
stack.push(Integer.parseInt(tokens[i]));
}
//因为题目中所述,只会出现加减乘除,即都是需要两个数来完成运算
//所以要出栈两次
else{
int num1=stack.pop();
int num2=stack.pop();
if(tokens[i].equals("+")){
stack.push(num2+num1);
}
else if(tokens[i].equals("-")){
stack.push(num2-num1);
}
else if(tokens[i].equals("*")){
stack.push(num2*num1);
}
else{
stack.push(num2/num1);
}
}
}
return stack.pop();
}
}