LeetCode Implement Stack using Queues and Implement Queue using Stacks(通过队列实现栈及通过栈实现队列)

       今天有在剑指offer一书中看一些算法题,结果早上看了剑指offer下午在LeetCode中做题时就碰到了相同的题目,而且觉着这个问题的解决对我们还是有很大帮助的,所以有必要跟大家分享一下哈~

通过队列实现栈:

Implement the following operations of a stack using queues.

  • push(x) -- Push element x onto stack.
  • pop() -- Removes the element on top of the stack.
  • top() -- Get the top element.
  • empty() -- Return whether the stack is empty.
Notes:
  • You must use only standard operations of a queue -- which means only push to back, peek/pop from front, size, and is empty operations are valid.
  • Depending on your language, queue may not be supported natively. You may simulate a queue by using a list or deque (double-ended queue), as long as you use only standard operations of a queue.
  • You may assume that all operations are valid (for example, no pop or top operations will be called on an empty stack).

       怎样通过队列实现栈呢,我们可以设计两个队列,一个是数据队列,另一个是辅助队列,模拟栈的先进后出,队列是队尾进队头出,也就是说每次取值要取队列的队尾元素,数据队列出队到辅助队列,留下最后一个元素返回,辅助队列再把元素出队到数据队列。当然我们毕竟号称精通Java语言,因此自然不会忘掉Deque这个双端队列接口啦,通过这个接口的方法定义我们只创建一个队列就能实现栈了。因此我们也就有了下面的两种实现:

       Deque实现:

package com.gaoxue.LeetCode;

import java.util.Deque;
import java.util.LinkedList;

public class MyStack2 {

	Deque<Integer> queue;
	public MyStack2() {
	    queue = new LinkedList<>();
	}
	public void push(int x) {
	    queue.offer(x);
	}
	public int pop() {
	    return queue.pollLast();
	}
	public int top() {
	    return queue.peekLast();
	}
	public boolean empty() {
	    return queue.isEmpty();
	}
}

       Queue实现:

package com.gaoxue.LeetCode;

import java.util.LinkedList;
import java.util.Queue;

public class MyStack {

	Queue<Integer> q = new LinkedList<Integer>();
    Queue<Integer> q2 = new LinkedList<Integer>();
    public MyStack() {}
    public void push(int x) {
        q.offer(x);
    }
    public int pop() {
        if(!q.isEmpty()){
            while(q.size()>1)
                q2.offer(q.poll());
        }
        int result = q.poll();
        while(!q2.isEmpty())
            q.offer(q2.poll());
        return result;
    }
    public int top() {
        if(!q.isEmpty()){
            while(q.size()>1)
                q2.offer(q.poll());
        }
        int result = q.peek();
        q2.offer(q.poll());
        while(!q2.isEmpty())
            q.offer(q2.poll());
        return result;
    }
    public boolean empty() {
            return q.isEmpty();
    }
    public static void main(String[] args) {
		MyStack myStack = new MyStack();
		MyStack2 myStack2 = new MyStack2();
		myStack.push(1);
		myStack.push(2);
		myStack.push(3);
		myStack2.push(1);
		myStack2.push(2);
		myStack2.push(3);
		System.out.println(myStack.pop()+" "+myStack2.pop());
		System.out.println(myStack.top()+" "+myStack2.top());
	}
}

       其实逻辑代码比较少,多为一些方法调用难度不是很大,下面我们来看一下怎样用栈去实现队列呢?

Implement the following operations of a queue using stacks.

  • push(x) -- Push element x to the back of queue.
  • pop() -- Removes the element from in front of queue.
  • peek() -- Get the front element.
  • empty() -- Return whether the queue is empty.
Notes:
  • You must use only standard operations of a stack -- which means only push to top, peek/pop from top, size, and is empty operations are valid.
  • Depending on your language, stack may not be supported natively. You may simulate a stack by using a list or deque (double-ended queue), as long as you use only standard operations of a stack.
  • You may assume that all operations are valid (for example, no pop or peek operations will be called on an empty queue).

       思路与上面相同,我们可以设计两个栈,一个用来放数据(数据栈),一个用来辅助(辅助栈)。数据添加时,会依次压栈,取数据时肯定会取栈顶元素,但我们想模拟队列的先进先出,所以就得取栈底元素,那么辅助栈就派上用场了,把数据栈的元素依次弹出到辅助栈,但保留最后一个元素,最后数据栈就剩下了最后一个元素,直接把元素返回,这时数据栈已经没有了数据。最后呢,把辅助栈的元素依次压人数据栈,这样则成功取到了栈底元素。下面是我的Java实现:

package com.gaoxue.LeetCode;

import java.util.Stack;

public class MyQueue {

	Stack<Integer> s = null;
    Stack<Integer> s2 = null;
    public MyQueue() {
        s = new Stack<Integer>();
        s2 = new Stack<Integer>();
    }
    public void push(int x) {
            s.push(x);
    }
    public int pop() {
        if(s2.isEmpty()){
            while(!s.isEmpty())
                s2.push(s.pop());
        }
        return s2.pop();
    }
    public int peek() {
        if(s2.isEmpty()){
            while(!s.isEmpty())
                s2.push(s.pop());
        }
        return s2.peek();
    }
    public boolean empty() {
        return s.isEmpty()&&s2.isEmpty();
    }
    public static void main(String[] args) {
		MyQueue myQueue = new MyQueue();
		myQueue.push(1);
		myQueue.push(2);
		myQueue.push(3);
		System.out.print(myQueue.pop()+" ");
		System.out.print(myQueue.peek()+" ");
		System.out.print(myQueue.pop());
	}
}
       其实也很简单吧,栈和队列是数据结构相当重要的一个模块,当你把这两道题搞懂的时候有没有觉着对栈和队列的相关问题明朗了许多呢,没错只要你肯努力,定可以乘风破浪~


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
引用\[1\]提供了一个朴素的解法,使用两个来存储字符串,一个用来存储普通字符,另一个用来存储特殊字符。遍历字符串,如果是普通字符则压入第一个,如果是特殊字符则弹出第一个顶元素。最后比较两个是否相同即可判断字符串是否有效。这个解法的时间复杂度是O(M + N),空间复杂度也是O(M + N)。\[1\] 引用\[2\]提供了另一个的应用场景,即判断括号是否有效。遍历字符串,如果是左括号则压入,如果是右括号则判断和顶元素是否匹配,不匹配则返回false,匹配则弹出顶元素。最后判断是否为空即可判断括号是否有效。\[2\] 引用\[3\]也提供了一个判断括号是否有效的解法,使用来操作。遍历字符串,如果是左括号则压入,如果是右括号则判断和顶元素是否匹配,不匹配则返回false,匹配则弹出顶元素。最后判断是否为空即可判断括号是否有效。这个解法使用了HashMap来存储括号的对应关系。\[3\] 综上所述,在解决字符串相关问题中有着广泛的应用,包括判断字符串是否有效、逆波兰表达式等。在解决这些问题时,可以帮助我们保存和处理字符的顺序,从而简化问题的处理过程。 #### 引用[.reference_title] - *1* *3* [Leetcode刷题03-](https://blog.csdn.net/weixin_47802917/article/details/123007699)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v4^insert_chatgpt"}} ] [.reference_item] - *2* [leetCode-类型详解](https://blog.csdn.net/zhiyikeji/article/details/125508011)[target="_blank" data-report-click={"spm":"1018.2226.3001.9630","extra":{"utm_source":"vip_chatgpt_common_search_pc_result","utm_medium":"distribute.pc_search_result.none-task-cask-2~all~insert_cask~default-1-null.142^v91^insertT0,239^v4^insert_chatgpt"}} ] [.reference_item] [ .reference_list ]

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值