zoukankan      html  css  js  c++  java
  • 两个队列实现一个栈

    问题描述:

    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 backpeek/pop from frontsize, 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).

    link: https://leetcode.com/problems/implement-stack-using-queues/

    解决思路:

    <思路1>

    假设有两个队列,分别为q1和q2. 对数据元素进行操作时使用q1,将q2作为辅助的数据缓存的队列。具体做法如下:

    (1) push时,直接将需要push的元素加到q1中;

    (2) pop时,首先检查q1是否为空,如果不为空则将q1中的元素都poll到q2中,直到q1中的元素剩余一个为止,剩下的这个元素即为需要pop的元素,poll即可;

    (3) peek时,与(2)中的pop类似,区别在于最后不poll,保留该值,最终返回即可。

    (4) isEmpty()只需要检查q1.size()是否为0;

    <代码>

    class MyStack {
        private Queue<Integer> q1;
        private Queue<Integer> q2;
        
        public MyStack() {
            q1 = new LinkedList<Integer>();
            q2 = new LinkedList<Integer>();
        }
        
        // Push element x onto stack.
        public void push(int x) {
            q1.offer(x);
        }
    
        // Removes the element on top of the stack.
        public void pop() {
            if (q1.size() == 0) {
                return ;
            }
            while (q1.size() > 1) {
                q2.offer(q1.poll());
            }
            q1.poll();
            while (q2.size() > 0) {
                q1.offer(q2.poll());
            }
        }
    
        // Get the top element.
        public int top() {
            if (q1.size() == 0) {
                return -1;
            }
            while (q1.size() > 1) {
                q2.offer(q1.poll());
            }
            int res = q1.poll();
            q2.offer(res);
            while (q2.size() > 0) {
                q1.offer(q2.poll());
            }
            return res;
        }
    
        // Return whether the stack is empty.
        public boolean empty() {
            return q1.size() == 0;
        }
    }
    

    <思路2>

    思路1中每次pop操作之后,都要将q2中的元素倒回q1中,这样做的的优点可以使得push操作更简单,但是缺点在于效率不高。下面考虑另一种思路,使用两个指针pushTmp和tmp来标记进出栈操作对应的队列和中间缓存的队列,只要这两种类型的队列确定了,对应的pop和push操作和思路1中的是一样的。tmp对应的队列通常为空。

    <代码>

    class MyStack {
        private Queue<Integer> q1;
        private Queue<Integer> q2;
        
        private Queue<Integer> pushTmp;
        private Queue<Integer> tmp;
        
        public MyStack() {
            q1 = new LinkedList<Integer>();
            q2 = new LinkedList<Integer>();
        }
        
        // Push element x onto stack.
        public void push(int x) {
            if (q1.size() == 0) {
                pushTmp = q2;
            } else {
                pushTmp = q1;
            }
            pushTmp.offer(x);
        }
    
        // Removes the element on top of the stack.
        public void pop() {
            if (q1.size() == 0) {
                tmp = q1;
                pushTmp = q2;
            } else {
                tmp = q2;
                pushTmp = q1;           
            }
            if (pushTmp.size() == 0) {
                return ;
            }
            while (pushTmp.size() > 1) {
                tmp.offer(pushTmp.poll());
            }
            pushTmp.poll();
        }
    
        // Get the top element.
        public int top() {
            if (q1.size() == 0) {
                tmp = q1;
                pushTmp = q2;
            } else {
                tmp = q2;
                pushTmp = q1;           
            }
            if (pushTmp.size() == 0) {
                return -1;
            }
            while (pushTmp.size() > 1) {
                tmp.offer(pushTmp.poll());
            }
            int res = pushTmp.poll();
            tmp.offer(res);
            return res;
        }
    
        // Return whether the stack is empty.
        public boolean empty() {
            return q1.size() == 0 && q2.size() == 0;
        }
    }
    

    拓展问题:两个栈实现一个队列

    <思路1>

    假设有两个栈分别为S1和S2,按照以下方法来模拟队列:

    (1) 元素进队列:直接将元素push到S1中;

    (2) 元素出队列:首先检查S2是否为空,如果不为空则S2.pop()即可;如果为空,则将S1中的所有元素都pop并且push到S2中(如果S1为空则抛出抛出异常)。

    <代码>

    class MyQueue{
    	private Stack<Integer> s1;
    	private Stack<Integer> s2;
    	
    	public MyQueue() {
    		s1 = new Stack<Integer>();
    		s2 = new Stack<Integer>();
    	}
    	
    	public void offer(int elem){
    		s1.push(elem);
    	}
    	
    	public int poll() {
    		if (!s2.isEmpty()) {
    			return s2.pop();
    		}
    		if (s1.isEmpty()) {
    			return -1;
    		}
    		while (!s1.isEmpty()) {
    			s2.push(s1.pop());
    		}
    		return s2.pop();
    	}
    	
    	public int peek() {
    		if (!s2.isEmpty()) {
    			return s2.peek();
    		}
    		while (!s1.isEmpty()) {
    			s2.push(s1.pop());
    		}
    		return s2.peek();
    	}
    }
    
  • 相关阅读:
    HDU4529 郑厂长系列故事——N骑士问题 —— 状压DP
    POJ1185 炮兵阵地 —— 状压DP
    BZOJ1415 聪聪和可可 —— 期望 记忆化搜索
    TopCoder SRM420 Div1 RedIsGood —— 期望
    LightOJ
    LightOJ
    后缀数组小结
    URAL
    POJ3581 Sequence —— 后缀数组
    hdu 5269 ZYB loves Xor I
  • 原文地址:https://www.cnblogs.com/harrygogo/p/4580114.html
Copyright © 2011-2022 走看看