栈与队列Part2

栈与队列Part2

一、20. 有效的括号

文章链接

1. 思路分析

  • 原理:栈先入后出特点恰好与本题括号排序特点一致,即若遇到左括号入栈,遇到右括号时将对应栈顶左括号出栈,则遍历完所有括号后 stack 仍然为空。

经过分析,本题有三种错误情况:

  1. 左括号冗余:遍历过后得到的栈不为空。
  2. 右括号冗余:遍历到右括号时,栈已经空了。
  3. 括号类型不匹配:栈顶字符与当前字符不匹配。

2. 解法分析

大概就是遍历,入栈或者匹配。最后再判个空。

3. 代码展示

class Solution {
    public boolean isValid(String s) {
        Stack<Character> stack =  new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            // 存右括号,方便对比。
            if (s.charAt(i) == '(')
                stack.push(')');
            else if (s.charAt(i) == '{')
                stack.push('}');
            else if (s.charAt(i) == '[')
                stack.push(']');
            else {
                if (stack.empty())
                    return false; // 无左括号配对
                if (stack.peek() != s.charAt(i))
                    return false; // 类型不匹配
                stack.pop();
            }
        }
        return stack.empty(); // 有无右括号配对。简洁写法。
    }
}

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

文章链接

1. 思路分析

本题是很经典的对于栈结构的应用。原理显而易见,区别在具体的实现方法

2. 解法分析

比较好的优化算法是,创建一个StringBuffer,并将其作为一个栈来用。最后消除出来的就是我们需要的结果。

与我第一时间想到的方案相比,现在的算法对StringBuffer的增删操作都是 O ( 1 ) O(1) O(1),非常省时。

以及StringBuffer的删除单个字符方法名为deleteCharAt().

3. 代码展示

class Solution {
    public String removeDuplicates(String s) {
        // 将 StringBuffer 当做栈
        StringBuffer sb = new StringBuffer();
        // top为 sb 的长度
        int top = -1;
        for (int i = 0; i < s.length(); i++) {
            char c = s.charAt(i);
            // 当 top > 0,即栈中有字符时,当前字符如果和栈中字符相等,弹出栈顶字符,同时 top--
            if (top >= 0 && sb.charAt(top) == c) {
                sb.deleteCharAt(top);
                top--;
            // 否则,将该字符 入栈,同时top++
            } else {
                sb.append(c);
                top++;
            }
        }
        return sb.toString();
    }
}

三、150. 逆波兰表达式求值

文章链接

1. 思路分析

早在去年就已经被栈计算器反反复复磨了好久,逆波兰的输入简化了括号问题,真的简单了很多。由于不用担心异常处理,所以写起来也很顺畅。

2. 解法分析

几点注意:

  • Java中’'表示基本数据类型字符,而""才能表示字符串。
    和字符串作比较要用"",以及.equals()
  • parseInt()方法返回基本数据类型int,而valueOf()方法返回Integer对象。

3. 代码展示

class Solution {
    public int evalRPN(String[] tokens) {
        // 应该...不用做异常处理吧
        Stack<Integer> stack = new Stack<>();
        for (String s : tokens) {
            // Java中''表示基本数据类型字符,而""才能表示字符串。
            // 和字符串作比较要用""
            if (s.equals("+")) {
                int sr = stack.pop();
                int sl = stack.pop();
                stack.push(sr + sl);
            }
            else if (s.equals("-")) {
                int sr = stack.pop();
                int sl = stack.pop();
                stack.push(sl - sr);
            }
            else if (s.equals("*")) {
                int sr = stack.pop();
                int sl = stack.pop();
                stack.push(sl * sr);
            }
            else if (s.equals("/")) {
                int sr = stack.pop();
                int sl = stack.pop();
                stack.push(sl / sr);
            }
            else {
                // parseInt()方法返回基本数据类型int,而valueOf()方法返回Integer对象。
                stack.push(Integer.parseInt(s));
            }
        }
        return stack.peek();
    }
}

四、总结

爱栈。

  • 24
    点赞
  • 14
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值