java算法第十一天 | ● 20. 有效的括号 ● 1047. 删除字符串中的所有相邻重复项 ● 150. 逆波兰表达式求值

本文介绍了Java中的Deque接口,特别是ArrayDeque和LinkedList两种实现,讨论了它们作为栈和队列的特性和使用场景。通过举例说明如何用Deque解决括号匹配、删除重复字符和逆波兰表达式求值等问题。
摘要由CSDN通过智能技术生成

这里要先讲一下Deque实现栈与队列(参考文章)

Java中实际上提供了java.util.Stack来实现栈结构,但官方目前已不推荐使用,而是使用java.util.Deque双端队列来实现队列与栈的各种需求
ava.util.Deque的实现子类有

java.util.LinkedList //基于链表,

java.util.ArrayDeque //基于数组实现的双端队列.

Deque总体介绍

要讲栈和队列,首先要讲Deque接口。Deque的含义是“double ended queue”,即双端队列,它既可以当作栈使用,也可以当作队列使用

  • 下表列出了Deque与Stack相对应的接口:
    在这里插入图片描述
  • 下表列出了Deque与Queue相对应的接口:
    在这里插入图片描述
    上面两个表共定义了Deque的12个接口。添加,删除,取值都有两套接口,它们功能相同,区别是对失败情况的处理不同。一套接口遇到失败就会抛出异常,另一套遇到失败会返回特殊值(false或null)。除非某种实现对容量有限制,大多数情况下,添加操作是不会失败的。虽然Deque的接口有12个之多,但无非就是对容器的两端进行操作,或添加,或删除,或查看。明白了这一点讲解起来就会非常简单。
    ArrayDeque和LinkedList是Deque的实现子类,他们都能使用Deque的这12个方法,包括isEmpty()判断是否为空方法和size()栈和队列的大小。
ArrayDeque

从名字可以看出ArrayDeque底层通过数组实现,为了满足可以同时在数组两端插入或删除元素的需求,该数组还必须是循环的,即循环数组(circular array),也就是说数组的任何一点都可能被看作起点或者终点。ArrayDeque是非线程安全的(not thread-safe),当多个线程同时使用的时候,需要程序员手动同步;另外,该容器不允许放入null元素。

LinkedList

LinkedList实现了Deque接口,因此其具备双端队列的特性,由于其是链表结构,,双向链表,因此不像ArrayDeque要考虑越界问题,容量问题,那么对应操作就很简单了(另外当需要使用栈和队列是官方推荐的是ArrayDeque)。

20. 有效的括号

leetcode链接
思路: 括号匹配是使用栈解决的经典问题。
建议在写代码之前要分析好有哪几种不匹配的情况,如果不在动手之前分析好,写出的代码也会有很多问题。
在这里插入图片描述
在这里插入图片描述
我们的代码只要覆盖了这三种不匹配的情况,就不会出问题,可以看出 动手之前分析好题目的重要性。
在这里插入图片描述

  • 第一种情况:已经遍历完了字符串,但是栈不为空,说明有相应的左括号没有右括号来匹配,所以return false

  • 第二种情况:遍历字符串匹配的过程中,发现栈里没有要匹配的字符。所以return false

  • 第三种情况:遍历字符串匹配的过程中,栈已经为空了,没有匹配的字符了,说明右括号没有找到对应的左括号return false

那么什么时候说明左括号和右括号全都匹配了呢,就是字符串遍历完之后,栈是空的,就说明全都匹配了。
java代码实现

class Solution {
    public boolean isValid(String s) {
        Deque<Character> stack=new LinkedList<>();
        for(int i=0;i<s.length();i++){
            char ch=s.charAt(i);
            if(ch=='('){
                stack.push(')');
            }else if(ch=='{'){
                stack.push('}');
            }else if(ch=='['){
                stack.push(']');
            }else if(stack.isEmpty() || stack.peek()!=ch){
                return false;
            }else{
                stack.pop();
            }
        }
        return stack.isEmpty();
    }
}

时间复杂度:O(n)
空间复杂度:O(n)

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

思路: 用栈实现相邻元素是否相同的判断,和有效括号的思路类似。
在这里插入图片描述
java代码实现

class Solution {
    public String removeDuplicates(String s) {
        Deque<Character> stack=new ArrayDeque<>();
        for(int i=0;i<s.length();i++){
            char ch=s.charAt(i);
            if(stack.isEmpty() || stack.peek()!=ch){
                stack.push(ch);
            }else{
                stack.pop();            
                }
        }
        String res="";
        while(!stack.isEmpty()){
            res=stack.pop()+res;
        }
        return res;
    }
}

时间复杂度:O(n)
空间复杂度:O(n)

150. 逆波兰表达式求值

思路: 栈的典型使用
在这里插入图片描述
注意:

  • 注意 - 和/ 需要特殊处理
  • leetcode 内置jdk的问题,不能使用==判断字符串是否相等
class Solution {
    public int evalRPN(String[] tokens) {
        Deque<Integer> stack=new LinkedList<>();
        for(String s:tokens){
            if(s.equals("+")){
                stack.push(stack.pop()+stack.pop());
            }else if(s.equals("*")){
                stack.push(stack.pop()*stack.pop());
            }else if(s.equals("-")){
                int temp1=stack.pop();
                int temp2=stack.pop();
                stack.push(temp2-temp1);
            }else if(s.equals("/")){
                int temp1=stack.pop();
                int temp2=stack.pop();
                stack.push(temp2/temp1);
            }else{
                stack.push(Integer.valueOf(s));
            }
        }
        return stack.pop();
    }
}

时间复杂度:O(n)
空间复杂度:O(n)

  • 21
    点赞
  • 27
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值