算法练习(52): 双向队列与栈(1.3.48-1.3.50)

本系列博客习题来自《算法(第四版)》,算是本人的读书笔记,如果有人在读这本书的,欢迎大家多多交流。为了方便讨论,本人新建了一个微信群(算法交流),想要加入的,请添加我的微信号:zhujinhui207407 谢谢。另外,本人的个人博客 http://www.kyson.cn 也在不停的更新中,欢迎一起讨论

算法(第4版)

知识点

  • 队列、栈或 steque

题目

1.3.48 双向队列与栈。用一个双向队列实现两个栈,保证每个栈操作只需要常数次的双向队列操作。(请见练习 1.3.33)


1.3.48 Two stacks with a deque. Implement two stacks with a single deque so that each operation takes a constant number of deque operations (see Exercise 1.3.33).

分析

要实现一个栈,即是实现栈的 push,pop 等操作。

public class  Stack<Item> {
    private int N = 0;
    private Node topNode = null;
    private class Node {
        Item item;
        Node next;
    }

    private Deque<Item> deque;


    public void push(Item item) {
        if (deque == null) {
            deque = new Deque<Item>();
        }
        deque.pushRight(item);
    }

    public Item pop() {
        return deque.popRight();
    }

    public boolean isEmpty() {
        return deque.isEmpty();
    }

    public int size() {
        return deque.size();
    }
}

测试用例

 public static void main(String[] args) {
    Stack<String> stack = new Stack();
    stack.push("I");
    stack.push("am");
    stack.push("Kyson");
    stack.push("You");
    stack.push("are");

    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());

    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());

    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());


    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());

    System.out.println(stack.pop());
    System.out.println("size:" + stack.size());
}

题目

1.3.49 栈与队列。用三个栈实现一个队列,保证每个队列操作(在最坏情况下)都只需要常数次的栈操作。


1.3.49 Queue with three stacks. Implement a queue with three stacks so that each queue operation takes a constant (worst-case) number of stack operations. Warning : high degree of difficulty.

分析

queue.new() : Stack1 = Stack.new(<Stack>);  
              Stack2 = Stack1;  

enqueue(element): Stack3 = Stack.new(<TypeOf(element)>); 
                  Stack3.push(element); 
                  Stack2.push(Stack3);
                  Stack3 = Stack.new(<Stack>);
                  Stack2.push(Stack3);
                  Stack2 = Stack3;                       

dequeue(): Stack3 = Stack1.pop(); 
           Stack1 = Stack1.pop();
           dequeue() = Stack1.pop()
           Stack1 = Stack3;

isEmtpy(): Stack1.isEmpty();

演示如下:

 | | | |3| | | |
 | | | |_| | | |
 | | |_____| | |
 | |         | |
 | |   |2|   | |
 | |   |_|   | |
 | |_________| |
 |             |
 |     |1|     |
 |     |_|     |
 |_____________|

题目

1.3.50 快速出错的迭代器。修改 Stack 的迭代器代码,确保一旦用例在迭代器中(通过 push() 或 pop() 操作)修改集合数据就抛出一个 java.util.ConcurrentModificationException 异常。


1.3.50 Fail-fast iterator. Modify the iterator code in Stack to immediately throw a java.util.ConcurrentModificationException if the client modifies the collection (via push() or pop()) during iteration? b).
Solution: Maintain a counter that counts the number of push() and pop() operations. When creating an iterator, store this value as an Iterator instance variable. Before each call to hasNext() and next(), check that this value has not changed since con- struction of the iterator; if it has, throw the exception.

答案

public class Stack<Item> implements Iterable<Item>
{
    private int N;
    private Node first;
    private int pushPopCount;
    
    private class Node {
        Item item;
        Node next;
    }
    
    public Stack() {
    }
    
    public Stack(Stack s)
    {
        Node right=new Node();
        Node oldright;
        for(Object i:s) {
            oldright=right;
            right=new Node();
            right.item=(Item) i;
            right.next=null;
            if(isEmpty()) {
                first=right;
            } else {
                oldright.next=right;
            }
            N++;
        }
    }
    
    public boolean isEmpty() {
        return 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++;
        pushPopCount++;
    }
    
    public Item pop() {
        Item item=first.item;
        first=first.next;
        N--;
        pushPopCount++;
        return item;
    }
    
    
    public Item peek() {
        Item item=first.item;
        return item;
    }
    
    public void catenation(Stack s) {
        while(!s.isEmpty()) {
            this.push((Item)s.pop());
        }
    }
    
    public Iterator<Item> iterator() {
        return new ListIterator();
    }
    
    private class ListIterator implements Iterator<Item> {
        private Node current=first;
        private int originatedPushPopCount;
        public ListIterator() {
            originatedPushPopCount=pushPopCount;
        }
        public boolean hasNext() {
            return current!=null;
        }
        public void remove(){}
        public Item next()
        {
            if(originatedPushPopCount!=pushPopCount)
                throw new java.util.ConcurrentModificationException();
            Item item=current.item;
            current=current.next;
            return item;
        }
    }
}

参考

How to implement a queue with three stacks?

广告

我的首款个人开发的APP壁纸宝贝上线了,欢迎大家下载。

最后编辑于
©著作权归作者所有,转载或内容合作请联系作者
【社区内容提示】社区部分内容疑似由AI辅助生成,浏览时请结合常识与多方信息审慎甄别。
平台声明:文章内容(如有图片或视频亦包括在内)由作者上传并发布,文章内容仅代表作者本人观点,简书系信息发布平台,仅提供信息存储服务。

相关阅读更多精彩内容

  • 背景 一年多以前我在知乎上答了有关LeetCode的问题, 分享了一些自己做题目的经验。 张土汪:刷leetcod...
    土汪阅读 14,358评论 0 33
  • 新絮飞,荻花殇,满地凄凉。残酒回肠,一段情,两断伤。怎叫梨花雨凉? 茫茫清溪霜含月,孤帆夜影,残雁点点...
    石石头阅读 2,806评论 0 2
  • 第一次听说大冰,是最恋军时节,当时以为是一个很厉害的兵哥哥。待到朋友解释此“冰”非彼“兵”时,一脸的不屑,暗叹此人...
    剑羽风凌阅读 4,944评论 0 1
  • 北上广的你痛并快乐着 2017-10-20 小曜 沸腾的城与孤独的人 作者 小曜 熙熙攘攘的地铁...
    田野同学阅读 1,670评论 0 2
  • 作为88届奥斯卡最佳动画长片,较之《疯狂动物城》在中国市场的红红火火、老少通吃,《头脑特工队》在中国电影市场并没有...
    卡萨布兰卡遥望佛罗伦萨阅读 3,068评论 0 1

友情链接更多精彩内容