• 算法-第四版-练习1.3.3解答


    假设某个用例程序会进行一系列入栈和出栈操作。入栈操作会将整数0到9按顺序压入栈;出栈操作会打印返回值。下面哪种顺序是不可能产生的?

    (a)  4 3 2 1 0 9 8 7 6 5
    (b)  4 6 8 7 5 3 2 9 0 1
    (c)  2 5 6 7 4 8 9 3 1 0
    (d)  4 3 2 1 0 5 6 7 8 9
    (e)  1 2 3 4 5 6 9 8 7 0
    (f)  0 4 6 5 3 8 1 7 2 9
    (g)  1 4 7 9 8 6 5 3 0 2
    (h)  2 1 4 3 6 5 8 7 9 0

    分析3个数时的入栈与出栈操作,所有的顺序有3!种。分别为:

    1 2 3
    1 3 2
    2 1 3
    2 3 1
    3 1 2
    3 2 1

    解法一

    可以知道只有 3 1 2 这种顺序不可能的,将其推广就可以得到这种的规律:

    大 小 中

    这种顺序是不能出现的。

    如上述中(b)中的9 0 1,(f)中的8 1 7,(g)中的3 0 2。所以b, f, g是不能产生的。

    解法二

    本文采用另一种思路来解决这个问题。

    就假设上述都是合法序列,即都是由出栈产生的,那么应该能将些序列作为出入通过入栈与出栈操作,得到一个顺序的序列。

    而问题在于入栈的方向、与得到顺序序列是升序还是降序呢?

    显然逆过程应该是从上述输出的尾部开始入栈,而得到的序列应该也是逆序的。以(a)为例,从5开始入栈,一直到4。要得到9 8...1 0的序列。

    下面给出实现的代码,首先需要给Stack添加一个top()方法。

    /**
     * Description : 
     * Author      : mn@furzoom.com
     * Date        : Sep 27, 2016 5:07:34 PM
     * Copyright (c) 2013-2016, http://furzoom.com All Rights Reserved.
     */
    package com.furzoom.lab.algs.ch103;
    
    import java.util.Iterator;
    
    import edu.princeton.cs.algs4.StdIn;
    import edu.princeton.cs.algs4.StdOut;
    
    /**
     * ClassName    : Stack <br>
     * Function     : TODO ADD FUNCTION. <br>
     * date         : Sep 27, 2016 5:07:34 PM <br>
     * 
     * @version 
     */
    public class Stack<Item> implements Iterable<Item>
    {
        private Node first;
        private int n;
        private class Node
        {
            Item item;
            Node next;
        }
            
        public boolean isEmpty() 
        {
            return first == null;
        }
        
        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()
        {
            return first.item;
        }
           
        @Override
        public Iterator<Item> iterator()
        {
            return new ReverseArrayIterator();
        }
        
        private class ReverseArrayIterator implements Iterator<Item>
        {
            private Node p = first;
            @Override
            public boolean hasNext()
            {
                return p != null;
            }
    
           @Override
            public Item next()
            {
               Item item = p.item;
               p = p.next;
               return item;
            }
            
        }
    
        public static void main(String[] args)
        {
            Stack<String> s;
            s = new Stack<String>();
            while (!StdIn.isEmpty())
            {
                String item = StdIn.readString();
                if (!item.equals("-"))
                    s.push(item);
                else if (!s.isEmpty())
                    StdOut.print(s.pop() + " ");
            }
            StdOut.println("(" + s.size() + " left on stack)");
        }
    }
    

    测试用例:

    /**
     * Description : 
     * Author      : mn@furzoom.com
     * Date        : Sep 28, 2016 2:25:18 PM
     * Copyright (c) 2013-2016, http://furzoom.com All Rights Reserved.
     */
    package com.furzoom.lab.algs.ch103;
    
    import edu.princeton.cs.algs4.StdIn;
    
    /**
     * ClassName    : E10303 <br>
     * Function     : TODO ADD FUNCTION. <br>
     * date         : Sep 28, 2016 2:25:18 PM <br>
     * 
     * @version 
     */
    public class E10303
    {
        public static boolean isValid(int[] seq)
        {
            Stack<Integer> stack = new Stack<Integer>();
            int currentNum = 9;
            int index = 9;
            while (currentNum >= 0)
            {
                if (index >= 0 && seq[index] == currentNum)
                {
                    index--;
                    currentNum--;
                }
                else if (!stack.isEmpty() && stack.top() == currentNum)
                {
                    stack.pop();
                    currentNum--;
                }
                else 
                {
                    if (index < 0)
                        break;
                    stack.push(seq[index]);
                    index--;
                }
            }     
            return stack.isEmpty();
        }
        
        public static void main(String[] args)
        {
            while (!StdIn.isEmpty())
            {
                String line = StdIn.readLine();
                String[] values = line.split("\s+");
                int[] nums = new int[10];
    
                for (int i = 0; i < values.length; i++)
                {
                    nums[i] = Integer.parseInt(values[i]);
                }
    
                if (isValid(nums))
                {
                    System.out.println("OK");
                } 
                else
                {
                    System.out.println("No");
                }
            }
        }
    
    }
    

    结果如下 :

    >java -cp ".;../lib/algs4.jar" com
    .furzoom.lab.algs.ch103.E10303 < com/furzoom/lab/algs/ch103/E10303.txt
    OK
    No
    OK
    OK
    OK
    No
    No
    OK

    测试数据文件 E10303.txt为:

    4 3 2 1 0 9 8 7 6 5
    4 6 8 7 5 3 2 9 0 1
    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
    1 4 7 9 8 6 5 3 0 2
    2 1 4 3 6 5 8 7 9 0



    算法-第四版-1.3 背包、队列和栈-习题索引汇总

    算法-第四版习题索引汇总

    作者:马 岩Furzoom) (http://www.cnblogs.com/furzoom/
    版权声明:本文的版权归作者与博客园共同所有。转载时请在明显地方注明本文的详细链接,未经作者同意请不要删除此段声明,感谢您为保护知识产权做出的贡献。
  • 相关阅读:
    C# 3.0新特性
    WinForm上显示gif动画
    Sql Server中Case函数的使用(上篇)转载
    Jquery的$命名冲突:
    Sql Server中case函数的使用(下篇) 转载
    hdu 2544 2066 1874 2680
    伤感!
    hdu 1999 不可摸数
    hdu 1878欧拉回路
    hdu 2767
  • 原文地址:https://www.cnblogs.com/furzoom/p/7710207.html
Copyright © 2020-2023  润新知