栈和队列部分:20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

代码随想录算法训练营第10天 | 栈和队列部分:20. 有效的括号,1047. 删除字符串中的所有相邻重复项,150. 逆波兰表达式求值

栈和队列部分

20. 有效的括号

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。有效字符串需满足:左括号必须用相同类型的右括号闭合。左括号必须以正确的顺序闭合。每个右括号都有一个对应的相同类型的左括号。

思路:使用栈实现
如果遇到(,{,[,就将与之对应的字符串入栈,比如说遇到"(“,入栈”)“,因为后面需要和”)"进行比较
注意点:思路对了,但是感觉这个代码写的好难看,好多个if else堆起来
Stack中没有top方法,只有peek,pop,push,size等

public boolean isValid(String s) {
    Stack<Character> st=new Stack<>();
    if(s.length()%2!=0){
        return false;
    }
    //遍历字符串,实现入栈,出栈
    for(int i=0;i<s.length();i++){
        if(s.charAt(i)=='('){
            st.push(')');
        }else if(s.charAt(i)=='{'){
            st.push('}');
        }else if(s.charAt(i)=='['){
            st.push(']');
        }else if(!st.isEmpty() && s.charAt(i)!=st.peek()){
            return false;
        }else if(st.isEmpty()){
            return false;
        }else{
            st.pop();
        }
    }
    //这边是指所有的元素遍历完成之后,栈中是否还有元素
    if(st.size()!=0){
        return false;
    }
    return true;
    }

1047. 删除字符串中的所有相邻重复项

给出由小写字母组成的字符串 S,重复项删除操作会选择两个相邻且相同的字母,并删除它们。在 S 上反复执行重复项删除操作,直到无法继续删除。在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

输入:“abbaca”
输出:“ca”
解释:
例如,在 “abbaca” 中,我们可以删除 “bb” 由于两字母相邻且相同,这是此时唯一可以执行删除操作的重复项。之后我们得到字符串 “aaca”,其中又只有 “aa” 可以执行重复项删除操作,所以最后的字符串为 “ca”。

思路:使用栈来解决该问题,如果当前字符等于上一个字符那就让上一个字符出栈,继续比较下一个,否则的话就入栈
注意点:将栈中的元素添加到新的字符串的时候,遍历的i应该小于一个定值,而不是一个变化的量(比如:st.size(),因为它会随着出栈操作,栈中元素个数减少)

public String removeDuplicates(String s) {
      Stack<Character> st=new Stack<>();
      for(int i=0;i<s.length();i++){
          if(!st.isEmpty() && st.peek()==s.charAt(i)){
                st.pop();
          }else{
              st.push(s.charAt(i));
          }
      }
      StringBuilder sb=new StringBuilder();
      /*
      for(int i=0;i<st.size();i++){
          sb.append(st.pop());//之前没意识到这边会存在问题,因为i<st.size(),实际上由于pop操作,size一直在减少,但是i++,就会导致添加的元素减少
      }
      */
      int len=st.size();
      for(int i=0;i<len;i++){
          sb.append(st.pop());
      }
      return sb.reverse().toString();
    }

150. 逆波兰表达式求值

根据 逆波兰表示法,求表达式的值。有效的算符包括 +、-、*、/ 。每个运算对象可以是整数,也可以是另一个逆波兰表达式。注意 两个整数之间的除法只保留整数部分。可以保证给定的逆波兰表达式总是有效的。换句话说,表达式总会得出有效数值且不存在除数为 0 的情况。

思路:如果输入的是运算符的话,就出栈两次得到两个操作数,然后将运算结果入栈;如果输入的是数字字符的话,直接入栈
注意:感觉这个思路没有问题,但是字符的转换等等存在很大的问题

//这样写的话,总是最后一个运算字符出现转换的NumberFormatException,数字格式化异常的问题
public int evalRPN(String[] tokens) {
    Stack<String> st=new Stack<>();
    int len=tokens.length;
    for(int i=0;i<len;i++){
        if(tokens[i]!="-" || tokens[i]!="+" || tokens[i]!="*" || tokens[i]!="/"){
            st.push(tokens[i]);
        }else{
            if(tokens[i]=="-"){
                int a=(Integer.parseInt(st.pop()));
                        int b=(Integer.parseInt(st.pop()));
                        st.push(Integer.toString(b-a));
            }
            if(tokens[i]=="+"){
                int a=(Integer.parseInt(st.pop()));
                        int b=(Integer.parseInt(st.pop()));
                        
                        st.push(Integer.toString(b+a));
            }
            if(tokens[i]=="*"){
              int a=(Integer.parseInt(st.pop()));
              int b=(Integer.parseInt(st.pop()));
              int res=a*b;
              st.push(String.valueOf(res));
            }
            if(tokens[i]=="/"){
              int a=(Integer.parseInt(st.pop()));
                        int b=(Integer.parseInt(st.pop()));
                        st.push(Integer.toString(b/a));
            }
            st.push(tokens[i]);
        }
     }
    return Integer.parseInt(st.pop());
    }

答案:又是==和equals的问题
leetcode内部只能用equals来判断,字符串是否相等
并且Stack采用Integer,而不是Character,这样就避免了后面的字符之间的转换

public int evalRPN(String[] tokens) {
    Stack<Integer> st=new Stack<>();//这里泛型中的具体值
    int len=tokens.length;
    for(int i=0;i<len;i++){
        if(tokens[i].equals("+")){//采用equals比较
            st.push(st.pop()+st.pop());
        }else if(tokens[i].equals("-")){
            int a=st.pop();
            int b=st.pop();
            st.push(b-a);
        }else if(tokens[i].equals("*")){
            st.push(st.pop()*st.pop());
        }else if(tokens[i].equals("/")){
            int a=st.pop();
            int b=st.pop();
            st.push(b/a);
        }else{
            st.push(Integer.valueOf(tokens[i]));//String到Integer的转换
        }
     }
    return st.pop();//这里包含了Integer的自动拆箱
    }

总结:利用栈的先进先出属性来做题
补充:类型之间的转换

String—>int:
1).int i = Integer.parseInt(str);
2). int i = Integer.valueOf(my_str).intValue();
int–>String
String s = String.valueOf(i);
String s = Integer.toString(i);
String s = “” + i;
String—>Integer
需要对String做非空判断,不然会造成空指针
if(str!=null){
i = Integer.valueOf(str);
}

Integer—>String
//方法一:Integer类的静态方法toString()
Integer a = 2;
String str = Integer.toString(a)
//方法二:Integer类的成员方法toString()
Integer a = 2;
String str = a.toString();
//方法三:String类的静态方法valueOf()
Integer a = 2;
String str = String.valueOf(a)

Integer—>int
1)Integer转换为int
Integer integer=new Integer(10);
int i=integer.intValue();
int j=(int)integer;
2)int转换为Integer
int i=10;
Integer integer=new Integer(i);
Integer integer=Integer.valueOf(i);

valueOf(), xxxxValue(), parse****()

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值