栈的压入压出(判断栈的压出顺序是否合法)

(1)问题描述
题目描述:
输入两个整数序列,第一个序列表示栈的压入顺序,请判断第二个序列是否为该栈的弹出顺序。
假设压入栈的所有数字均不相等。例如序列0,1,2,3,4,5,6,7,8,9是某栈的压入顺序,序列4 3 2 1 0 9 8 7 6 5是该压栈序列对应的一个弹出序列,但4 6 8 7 5 3 2 9 0 1就不可能是该压栈序列的弹出序列。

输入:
每个测试案例包括3行:
第一行为1个整数n(1<=n<=100000),表示序列的长度。
第二行包含n个整数,表示栈的压入顺序。
第三行包含n个整数,表示栈的弹出顺序。

输出:
对应每个测试案例,如果第二个序列是第一个序列的弹出序列输出Yes,否则输出No


(2)程序实现
栈的特点是后进先出,假设入栈的顺序是
A,B,C,D, E,F出栈的顺序为D C B A E F
操作顺序为111100001010(1:push 0:pop)
思路:最先出栈的是D,则必须先把A,B,C先放到栈中,再放上D,然后依次取出D C B A (因为它们等于当前栈顶元素),而E F则是push后立即pop
这里关键是一个元素要出栈,则必须进栈,而进栈必须考虑它前面的元素要先进去。


实现代码:

import java.util.Scanner;
public class test {
    public static class Stack<Item> {//static class用链表实现
        private Node first; // 栈顶(最近添加的元素)
        private int N; // 元素数量

        private class Node {
            // 定义了结点的嵌套类
            Item item;
            Node next;
        }

        public boolean isEmpty() {
            return first == null;// or N == 0;
        }

        public int size() {
            return N;
        }

        public void push(Item item) {
            // 向栈顶添加元素
            Node oldfirst = first;
            first = new Node();
            first.item = item;
            first.next = oldfirst;
            N++;
        }

        public Item pop() {
            // 从栈顶删除元素
            Item item = first.item;
            first = first.next;
            N--;
            return item;
        }

        public Item top() {
            //栈顶元素
            if (first != null) {
                return first.item;
            } else {
                return null;
            }
        }
    }
    static Scanner sc = new Scanner(System.in);
    public static void main(String[] args) {
        Stack<Integer> s = new Stack<Integer>();
        int n;
        int[] in = new int[100];//输入数据限定100个
        int[] out = new int[100];
        n = sc.nextInt();
        for (int i = 0; i < n; i++) {
            in[i] = sc.nextInt();
        }
        while (sc.hasNext()) {//允许输入多组数据
            for (int i = 0; i < n; i++) {
                out[i] = sc.nextInt();
            }
            //核心代码
            int index_in = 0;//输入数据索引
            int index_out = 0;//出栈数据索引
            boolean valid = true;//合法性标记
            for (; index_out < n; index_out++) {
                while (s.isEmpty() || out[index_out] != s.top()) {
                //当栈为空或者当前元素与栈顶元素不等
                    if (index_in < n) {
                        s.push(in[index_in++]);//不匹配栈顶元素,将元素压栈
                    }else if(out[index_out] != s.top()) {
                        valid = false;//已经push完所有数据,仍不能找到,则可以确定该顺序错误
                        break;
                    }
                }
                if (out[index_out] == s.top()) {
                    s.pop();//元素是栈顶的元素,则pop出来
                }
            }
            if (valid) {
                System.out.println("Yes");
            } else {
                System.out.println("No");
            }
            //System.out.println(index_out + " " + index_in);
        }
    }
}
/*
 * 测试样例 
 * 10                             每行输入10个数
 * 0 1 2 3 4 5 6 7 8 9            假定输入的数据为整数0-9
 * 
 * 4 3 2 1 0 9 8 7 6 5
 * 
 * 4 6 8 7 5 3 2 9 0 1            X
 * 
 * 2 5 6 7 4 8 9 3 1 0
 * 
 * 4 3 2 1 0 5 6 7 8 9
 * 
 * 1 2 3 4 5 6 9 8 7 0
 * 
 * 0 4 6 5 3 8 1 7 2 9            X
 * 
 * 1 4 7 9 8 6 5 3 0 2            X
 * 
 * 2 1 4 3 6 5 8 7 9 0
 * 
 */

最近在学习算法(第四版),该题目原型是出自该书1.3节习题1.3.3
入栈操作将整数0-9按顺序依次入栈,出栈操作打印返回值。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值