代码随想录刷题day11|有效的括号&删除字符串重复项&逆波兰表达式


day11学习内容

day11主要内容

  • 有效的括号
  • 删除字符串中的所有相邻重复项
  • 逆波兰表达式求值

一、 有效的括号

454原题链接

核心思路

1、思路比较巧妙吧,遇到是左括号,就直接入栈右括号。等下个字符串确实是右括号时,做一次出栈操作。如果出栈的元素不匹配,说明肯定多了一个左括号,return false即可。

1.正确写法1

class Solution {
    public static boolean isValid(String s) {
        Deque<Character> deque = new ArrayDeque<>();
        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();
    }
}

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

1047原题链接

1.正确写法1

class Solution {
    public String removeDuplicates(String s) {
        ArrayDeque<Character> deque = new ArrayDeque<>();
        for (int i = 0; i < s.length(); i++) {
            char 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;
    }
}

1、比较简单的一题,主要注意str = deque.pop() + str;不要写成了str += deque.pop() ;

简单分析一下为什么不能写反。
例如输入s=“aabc”,
在while之前,此时deque=“cb”,因此输出时要写成str = deque.pop() + str,最后输出字符串才会变成str=“bc”,才符合题意。


三、逆波兰表达式求值

150原题链接

1.什么是逆波兰表达式

逆波兰表达式就是一种后缀表达式。
1、中序表达式
平常看的比较舒服的,正常好理解的。
(1+2)*(3+4)
2、后缀表达式
12+34+*
3、计算机如何顺序处理(1+2)*(3+4)
计算机其实是使用栈来实现的

2.思路

一句话总结:遇见数字就入栈,遇见操作符就取出数字计算后再把计算结果重新入栈。

3.错误写法

class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack = new LinkedList();

        for (String s : tokens) {
            if (isNumber(s)) {
                stack.push(Integer.valueOf(s));
            } else {
                int temp1 = stack.pop();
                int temp2 = stack.pop();
                if ("+".equals(s)) {
                    stack.push(temp1 + temp2);
                } else if ("-".equals(s)) {
                    stack.push(temp1 - temp2);//这里错了
                } else if ("*".equals(s)) {
                    stack.push(temp1 * temp2);
                } else if ("/".equals(s)) {
                    stack.push(temp2 / temp1);
                }
            }
        }
        return stack.pop();
    }

    public boolean isNumber(String token) {
        return !("+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token));
    }

}

为什么这样写是错误的
1、假设tokens =[“4”,“3”,“-”]。
2、那么经过push以后,此时栈元素=[3,4],temp1=3,temp2=4,
3、计算stack.push(temp1 - temp2) == stack.push((3-4));
4、此时result=-1,不符合题意,所以错了。题意应该是4-3=1。

4.正确写法

class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack = new LinkedList();

        for (String s : tokens) {
            if (isNumber(s)) {
                stack.push(Integer.valueOf(s));
            } else {
                int temp1 = stack.pop();
                int temp2 = stack.pop();
                if ("+".equals(s)) {
                    stack.push(temp1 + temp2);
                } else if ("-".equals(s)) {
                    stack.push(temp2 - temp1);
                } else if ("*".equals(s)) {
                    stack.push(temp1 * temp2);
                } else if ("/".equals(s)) {
                    stack.push(temp2 / temp1);
                }
            }
        }
        return stack.pop();
    }

    public boolean isNumber(String token) {
        return !("+".equals(token) || "-".equals(token) || "*".equals(token) || "/".equals(token));
    }

}

总结

1.感想

  • 逆波兰表达式求值这一题,一开始逆波兰表达式是什么不知道。
  • 逆波兰表达式求值这一题,也想不到用栈解决,还是看了题解和视频才知道的。
  • 明天周日休息一天,再总结一下这周的题目吧,加油。

2.思维导图

本文思路引用自代码随想录,感谢代码随想录作者。

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值