剑指offer刷题总结——堆、栈、队列篇

1.用两个栈实现队列

【题目】

用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。 队列中的元素为 int 类型。

【代码】

package swear2offer.construction;

import java.util.Stack;

public class StackToQueue {

    /**
     * 用两个栈来实现一个队列,完成队列的 Push 和 Pop 操作。 队列中的元素为 int 类型。
     *
     * 栈的结构是先进后出,队列的结构是先进先出
     *  
     * */

    Stack<Integer> stack1 = new Stack<Integer>();
    Stack<Integer> stack2 = new Stack<Integer>();

    public void push(int node) {
        stack1.add(node);
    }

    public int pop() {
        if (stack2.empty()) {
            while (!stack1.empty()) {
                stack2.add(stack1.pop());
            }
        }

        return stack2.pop();
    }

}

【思路】

两个栈stack1和stack2,模拟队列的能力,插入元素直接插入stack1即可,因为存储元素只要保证保存下来,二者的区别关键是弹出元素的顺序,队列弹出的元素位于stack的最下面,所以需要把stack1的元素依次弹出,并放入stack2中,这样弹出元素的时候,只要stack2不为空,就弹出stack2的元素,stack2为空的时候,先把stack1的元素压入stack2,然后继续弹出stack2.


2.栈的压入、弹出序列

【题目】

输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否可能为该栈的弹出顺序。假设压入栈的所有数字均不相等。例如序列 1,2,3,4,5 是某栈的压入顺序,序列 4,5,3,2,1 是该压栈序列对应的一个弹出序列,但 4,3,5,1,2 就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)

【代码】

/**
     * 输入两个整数序列,第一个序列表示栈的压入顺序,
     * 请判断第二个序列是否可能为该栈的弹出顺序。
     * 假设压入栈的所有数字均不相等。例如序列 1,2,3,4,5 是某栈的压入顺序,
     * 序列 4,5,3,2,1 是该压栈序列对应的一个弹出序列,
     * 但 4,3,5,1,2 就不可能是该压栈序列的弹出序列。(注意:这两个序列的长度是相等的)
     * */

    public boolean IsPopOrder(int [] pushA,int [] popA) {

        int n,start,end,i,j;

        n = pushA.length;

        if (n == 0) return false;

        Stack<Integer> stack = new Stack<>();

        start = 0;
        end = GetIndex(pushA, popA[0]);

        if (end < 0) return false;

        // 把start和end之间的元素全部压入stack中
        for (j=start; j<=end; j++) {
            stack.add(pushA[j]);
        }

        start = end + 1;

        i = 0;
        while (i < n) {
            if (stack.peek() == popA[i]) {
                stack.pop();
                i++;
                continue;
            } else {
                end = GetIndex(pushA,popA[i]);
                if (start > end) return false;
                for (j=start; j<=end; j++) {
                    stack.add(pushA[j]);
                }
                start = end + 1;
            }
        }

        return true;

    }

    // 或者数组指定元素的下标
    public int GetIndex(int[] a, int target) {

        for(int i=0; i<a.length; i++) {
            if (a[i] == target) {
                return i;
            }
        }
        return -1;
    }

【思考】

while循环和for循环,同样的 i<n 的条件,最重要的区别就是,while循环的次数是不确定的(大于,小于,等于n次都可以),而for循环必定是小于等于n次的。

发布了196 篇原创文章 · 获赞 878 · 访问量 30万+

猜你喜欢

转载自blog.csdn.net/qq_33945246/article/details/104446375