• 两个队列实现一个栈


    问题描述:

    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();
    	}
    }
    
  • 相关阅读:
    控制流测试与条件测试
    12306的“短信公众号”到底是个啥?
    ISTQB名词辨析
    ISTQB TA
    启动Chrome时自动开启开发者模式
    LoadRunner Community Edition 12.60 无法获取Community License
    用言的活用声调变化规则
    ISTQB TTA大纲中提到的参考书目
    Java调用方法参数究竟是传值还是传址?
    Java中的Lambda表达式简介及应用
  • 原文地址:https://www.cnblogs.com/harrygogo/p/4580114.html
Copyright © 2020-2023  润新知