栈与队列——1047,150

今天继续学习栈与队列相关题目,今天两道题都是关于栈的。

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

删除字符串中的所有相邻重复项
本题如果没有了解过栈这种数据结构,也没有做过相关题目,我觉得还是不太容易想到的。因为就算我昨天做过括号匹配的题目,看到这道题的时候,下意识仍然是能否用多层循环遍历来暴力破解。然后我想到这是栈与队列相关题目,仔细一琢磨,和括号匹配有点类似。括号匹配是左右括号做匹配,这个是相同字母做匹配,匹配成功后都将其删除。

具体做法是,遍历字符串的每一个字符,如果与栈顶元素相同,则栈顶元素出栈,反之,该字符入栈。最后栈中剩余元素即为删除所有相同项后的字符串,但是栈内元素出栈的话顺序会与预计结果相反,需要进一步操作来颠倒顺序。可以再借助栈或者集合,我用的是StringBuilder类进行拼接。

	public static String removeDuplicates(String s){
        Stack<Character> stack=new Stack<>();
        for (int i = 0; i < s.length(); i++) {
            if (!stack.isEmpty()) {
                if (stack.peek()==s.charAt(i)){
                    stack.pop();
                }else {
                    stack.push(s.charAt(i));
                }
            }else {
                stack.push(s.charAt(i));
            }
        }
        StringBuilder sb=new StringBuilder();
        while (!stack.isEmpty()){
            sb.insert(0,stack.pop());
        }
        return sb.toString();
    }

LeetCode150.逆波兰表达式求值

逆波兰表达式求值

逆波兰表达式
逆波兰表达式也叫后缀表达式,这里是百度百科给的定义。在日常生活中数学表达式的写法是二叉树的中序遍历得到的顺序,而逆波兰式是后序遍历得到的结果。逆波兰式的好处是因为计算机使用了很多栈的内存结构,采取先进后出,后进先出的规则,所以使用这种表达式更利于计算机的阅读。

根据以上理论,再根据括号匹配和删除相同项两道题目,很容易想到用栈来解决问题,那么该如何正确使用栈来解决这道题呢?这道题第一时间可能会有所犹豫,因为括号匹配和删除相同项都是两两匹配,这道题其实是三个元素进行匹配,碰到运算符,出栈两个元素,这样的匹配方式。

具体逻辑是,使用一个栈来存储该表达式,如果是数字,则将其入栈,如果碰到运算符,将栈顶两个元素依次出栈后,根据运算符进行数学运算,将结果再次入栈,即一次匹配,两次出栈,一次入栈。

	public static int evalRPN(String[] tokens){
        Stack<String> stack=new Stack<>();
        int result=0;
        for (int i = 0; i < tokens.length; i++) {
            if (!stack.isEmpty()){
                if (tokens[i].equals("+")){
                    int temp1=Integer.parseInt(stack.pop());
                    int temp2=Integer.parseInt(stack.pop());
                    result=temp1+temp2;
                    stack.push(String.valueOf(result));
                }else if (tokens[i].equals("-")){
                    int temp1=Integer.parseInt(stack.pop());
                    int temp2=Integer.parseInt(stack.pop());
                    result=temp2-temp1;
                    stack.push(String.valueOf(result));
                }else if (tokens[i].equals("*")){
                    int temp1=Integer.parseInt(stack.pop());
                    int temp2=Integer.parseInt(stack.pop());
                    result=temp1*temp2;
                    stack.push(String.valueOf(result));
                }else if (tokens[i].equals("/")){
                    int temp1=Integer.parseInt(stack.pop());
                    int temp2=Integer.parseInt(stack.pop());
                    result=temp2/temp1;
                    stack.push(String.valueOf(result));
                } else {
                    stack.push(tokens[i]);
                }
            }else {
                stack.push(tokens[i]);
            }
        }
        return Integer.parseInt(stack.pop());
    }

需要注意一共有三点。第一点,这两道题都需要注意,当栈为空时,不能进行出栈操作,否则会报错,所以出栈的操作都应在判断过栈不为空的情况下执行。第二点,加和乘的运算顺序无所谓,因为根据数学知识,有交换律可以将两个数字进行交换顺序。但是如果是减法和除法,需要注意其顺序,哪一个元素是被减(除)数,哪一个是减(除)数。距离如果栈内元素为(3,2,4,6),假设右边为栈顶,下一个字符是"-",那么应该是,4-6,而不是6-4,如果顺序错误,将会导致结果错误,这里要注意出栈的先后顺序和运算的顺序。
第三点,多个if的并列和ifelse的区别。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值