Day09 | 232.用栈实现队列 225. 用队列实现栈 20. 有效的括号 1047. 删除字符串中的所有相邻重复项

语言

Java

232.用栈实现队列

题目链接:用栈实现队列

题目

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(pushpoppeekempty):

实现 MyQueue 类:

  • void push(int x) 将元素 x 推到队列的末尾
  • int pop() 从队列的开头移除并返回元素
  • int peek() 返回队列开头的元素
  • boolean empty() 如果队列为空,返回 true ;否则,返回 false

思路

用栈实现队列,想法就是定义两个栈,一个入栈一个出栈,元素放到入栈里,因为栈是先入后出的,再把元push到出栈中,就相当于实现了队列的先进先出。

代码

class MyQueue {
    Stack<Integer> stackIn;
    Stack<Integer> stackOut;
    public MyQueue() {
        stackIn = new Stack<>();
        stackOut = new Stack<>();
    }
    
    public void push(int x) {
        stackIn.push(x);
    }
    
    public int pop() {
        dumpstackIn();
        return stackOut.pop();
    }
    
    public int peek() {
        dumpstackIn();
        return stackOut.peek();
    }
    
    public boolean empty() {
        return stackIn.isEmpty() && stackOut.isEmpty();
    }
    
    private void dumpstackIn() {
        if (!stackOut.isEmpty()) return;
        while (!stackIn.isEmpty()) {
            stackOut.push(stackIn.pop());
        }
    }
}

易错点

其实这是一道模拟题,基本没有运用的算法。

注意写好各个方法就好了。

时间复杂度

  • 时间复杂度: push和empty为O(1), pop和peek为O(n)
  • 空间复杂度: O(n)

225. 用队列实现栈

题目链接:用队列实现栈

题目

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。

实现 MyStack 类:

void push(int x) 将元素 x 压入栈顶。
int pop() 移除并返回栈顶元素。
int top() 返回栈顶元素。
boolean empty() 如果栈是空的,返回 true ;否则,返回 false 。

思路

用一个队列实现栈,先把栈的元素放到队列中,然后把前size - 1个元素pop到后面,这样顺序就跟栈一样了。

代码 

class MyStack {

    Deque<Integer> que1;
    public MyStack() {
        que1 = new ArrayDeque<>();
    }
    
    public void push(int x) {
        que1.addLast(x);
    }
    
    public int pop() {
        int size = que1.size();
        size--;
        while (size-- > 0) {
            que1.addLast(que1.peekFirst());
            que1.pollFirst();
        }
        int res = que1.pollFirst();
        return res;
    }
    
    public int top() {
        return que1.peekLast();
    }
    
    public boolean empty() {
        return que1.isEmpty();
    }

易错点

这也是一道模拟的题,思路最重要,注意方法的使用。

时间复杂度

  • 时间复杂度: pop为O(n),其他为O(1)
  • 空间复杂度: O(n)

20. 有效的括号

题目链接:有效的括号

题目

给定一个只包括 '('')''{''}''['']' 的字符串 s ,判断字符串是否有效。

有效字符串需满足:

  1. 左括号必须用相同类型的右括号闭合。
  2. 左括号必须以正确的顺序闭合。
  3. 每个右括号都有一个对应的相同类型的左括号。

思路

先遍历字符串如果遇到左括号就将右括号放入栈中、如果遇到左花括号就将右花括号放入栈中、如果遇到左方括号就将右方括号放入栈中,最后如果相同进行消除。有三种情况,第一种字符串没遍历完栈为空了,第二种括号不能匹配,第三种遍历完了栈里还有元素。具体看代码

代码

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

易错点

有很多判断条件千万别落下了,判断栈是否为空,还有元素不匹配的情况,还有最后返回的是栈是否为空。

时间复杂度

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

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

题目链接:删除字符串中的所有相邻重复项

题目

给出由小写字母组成的字符串 S重复项删除操作会选择两个相邻且相同的字母,并删除它们。

在 S 上反复执行重复项删除操作,直到无法继续删除。

在完成所有重复项删除操作后返回最终的字符串。答案保证唯一。

思路

可以用栈模拟操作进行相邻的就消除,不过本体使用的是字符串,这样就可以直接省去把栈中元素再取出的过程。大体思路就是遇到相同的元素就消除。

代码

class Solution {
    public String removeDuplicates(String s) {
        StringBuffer res = new StringBuffer();
        int top = -1;
        for (int i = 0; i <s.length(); i++) {
            char c = s.charAt(i);
            if (top >= 0 && res.charAt(top) == c) {
                res.deleteCharAt(top);
                top--;
            } else {
                res.append(c);
                top++;
            }
        }
        return res.toString();
    }
}

易错点

注意把top设置成-1;代表字符串的长度。

循环中判断的时候别忘了判断top >= 0

时间复杂度

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

总结

今天开篇了栈和队列,这几道题主要是思路的模拟。先想好思路还是比较容易地。

明天继续加油,万丈高楼平地起。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值