【Leetcode之栈和队列】

9 篇文章 0 订阅


前言

题目来源


提示:以下是本篇文章正文内容,下面案例可供参考

1、用栈实现队列

请你仅使用两个栈实现先入先出队列。队列应当支持一般队列支持的所有操作(push、pop、peek、empty):
实现 MyQueue 类:

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

在这里插入图片描述

class MyQueue {
    Stack<Integer> stack1;
    Stack<Integer> stack2;
    public MyQueue() {
        stack1=new Stack<>();
        stack2=new Stack<>();
    }
    public void push(int x) {
         stack1.push(x);
    }
    public int pop() {
        if(!stack2.empty())
            return stack2.pop();
        while (!stack1.isEmpty())
            stack2.push(stack1.pop());
        return stack2.pop();
    }
    //peek指的是队列的第一个元素奥!!!
    public int peek() {
        if(!stack2.empty())
            return stack2.peek();
        while (!stack1.isEmpty())
            stack2.push(stack1.pop());
        return stack2.peek();
    }

    public boolean empty() {
        return stack1.empty() && stack2.empty();
    }
}

2、用队列实现栈

请你仅使用两个队列实现一个后入先出(LIFO)的栈,并支持普通栈的全部四种操作(push、top、pop 和 empty)。
实现 MyStack 类:
①void push(int x) 将元素 x 压入栈顶。
②int pop() 移除并返回栈顶元素。
③int top() 返回栈顶元素。
④boolean empty() 如果栈是空的,返回 true ;否则,返回 false
在这里插入图片描述

//直接使用Deque
//关于Queue与Deque的区别:https://blog.csdn.net/qq_41101966/article/details/127833999
class MyStack {
    Deque<Integer> deque;

    public MyStack() {
        deque=new LinkedList<>();
    }

    public void push(int x) {
        deque.addLast(x);
    }

    public int pop() {
        return deque.removeLast();
    }

    public int top() {
        return deque.peekLast();
    }

    public boolean empty() {
        return deque.isEmpty();
    }
}

3、最小值栈

设计一个支持 push ,pop ,top 操作,并能在常数时间内检索到最小元素的栈。
实现 MinStack 类:
①MinStack() 初始化堆栈对象。
②void push(int val) 将元素val推入堆栈。
③void pop() 删除堆栈顶部的元素。
④int top() 获取堆栈顶部的元素。
⑤int getMin() 获取堆栈中的最小元素。
在这里插入图片描述

//最小栈
//一个tips就是对于minstack每次都放入的是当前最小的
class MinStack {
    Stack<Integer> stack;
    Stack<Integer> minstack;
    public MinStack() {
        stack=new Stack<>();
        minstack=new Stack<>();
    }
    public void push(int val) {
        stack.push(val);
        if(minstack.isEmpty())
            minstack.push(val);
        else minstack.push(Math.min(minstack.peek(),val));
    }
    public void pop() {
        stack.pop();
        minstack.pop();
    }
    public int top() {
        return stack.peek();
    }
    public int getMin() {
        return minstack.peek();
    }
}

4、用栈实现括号匹配

给定一个只包括 ‘(’,‘)’,‘{’,‘}’,‘[’,‘]’ 的字符串 s ,判断字符串是否有效。
有效字符串需满足:
①左括号必须用相同类型的右括号闭合。
②左括号必须以正确的顺序闭合。
③每个右括号都有一个对应的相同类型的左括号
在这里插入图片描述

class Solution {
    public boolean isValid(String s) {
        int len=s.length();
        if(len%2==1) return false;
        Stack<Character> stack=new Stack<>();
        for(int i=0;i<len;++i){
            char c=s.charAt(i);
            if(c=='(' || c=='{' || c=='[')
                stack.push(c);
            else {
                if(stack.isEmpty()) return false;  //"))" 注意这里
                if(c==')') {
                    if(stack.pop()!='(') return false;
                }
                if(c=='}') {
                    if(stack.pop()!='{') return false;
                }
                if(c==']') {
                    if(stack.pop()!='[') return false;
                }
            } 
        } 
        //注意这里是要判空的!!
        if(stack.isEmpty()) return true;
        else return false;
    }
}

5、数组中元素与下一个比它大的元素之间的距离

给定一个整数数组 temperatures ,表示每天的温度,返回一个数组 answer ,其中 answer[i] 是指对于第 i 天,下一个更高温度出现在几天后。如果气温在这之后都不会升高,请在该位置用 0 来代替。
在这里插入图片描述

//其中cur是当前遍历到的位置;
//pre是在其前面的某个;
class Solution {
    public int[] dailyTemperatures(int[] temperatures) {
        int len=temperatures.length;
        Stack<Integer> stack=new Stack<>();
        int[] res=new int[len];
        for(int cur=0;cur<len;++cur){
            while (!stack.isEmpty() && temperatures[cur]>temperatures[stack.peek()]){
                int pre=stack.pop();
                res[pre]=cur-pre;
            }
            stack.push(cur);
        }
        return res;
    }
}

6、循环数组中比当前元素大的一个元素

给定一个循环数组 nums ( nums[nums.length - 1] 的下一个元素是 nums[0] ),返回 nums 中每个元素的 下一个更大元素 。
数字 x 的 下一个更大的元素 是按数组遍历顺序,这个数字之后的第一个比它更大的数,这意味着你应该循环地搜索它的下一个更大的数。如果不存在,则输出 -1 。
在这里插入图片描述

//跟上面那个题目的思想很类似,但是这个更“难”一点;
//循环数组用2*n就解决了
//而且要注意:Arrays.fill(res, -1);因为如果不存在就返回-1;
//注意:cur%len
//注意是while
class Solution {
        public int[] nextGreaterElements(int[] nums) {
        int len=nums.length;
        int[] res=new int[len];
        Arrays.fill(res, -1);
        Stack<Integer> stack=new Stack<>();
        for(int cur=0;cur<len*2;++cur){
            while(!stack.isEmpty() && nums[cur%len]>nums[stack.peek()]){   //这里是while
                res[stack.pop()]=nums[cur%len];
            }
            if(cur<len)
            stack.push(cur);
        }
        return res;
    }
}

总结

这部分题目并不多,主要是要注意终止条件吧。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值