Cracking the coding interview--Q3.3

题目

原文:

Imagine a (literal) stack of plates. If the stack gets too high, it might topple. Therefore, in real life, we would likely start a new stack when the previous stack exceeds some threshold. Implement a data structure SetOfStacks that mimics this. SetOfStacks should be composed of several stacks, and should create a new stack once the previous one exceeds capacity. SetOfStacks.push() and SetOfStacks.pop() should behave identically to a single stack (that is, pop() should return the same values as it would if there were just a single stack).
FOLLOW UP
Implement a function popAt(int index) which performs a pop operation on a specific sub-stack.

译文:

想象一下,一 堆盘子,如果堆得太高,它很可能会倒,因此在现实生活中,如果盘子堆到一定高度,我们就会重新起一个堆。现在实现一个新的数据结构SetOfStack来模拟这样现象。SetOfStack当中包含很多的堆栈,当一个堆栈达到上限的时候,启用下一个堆栈。SetOfStack.push 和 SetOfStack.pop应该和普通堆栈的操作一样。
进阶:
实现一个函数popAt(int index),指定在哪个堆栈上弹出元素。

解答

以下是书本的解答

由于要和普通的堆栈的push()有相同的效果,也就是说每次push()都必须将元素放到最近使用的一个堆栈中。但是在这个堆栈已经满了情况下,那就必须建一个新的堆栈然后再入栈。那么push的实现如下:

public void push(int v) {
		Stack last = getLastStack();
		if (last != null && !last.isAtCapacity()) { // add to last stack
			last.push(v);
		} else { // must create new stack
			Stack stack = new Stack(capacity);
			stack.push(v);
			stacks.add(stack);
		}
	}

那pop()如何实现呢?和push()差不多,也一定要在最近的一个堆栈上操作。但是如果最后一个堆栈是空的话,就应该将其移除。

public int pop()
    {
        Stack last = getLastStack();
        System.out.println(stacks.size());
        int v = last.pop();
        if (last.size == 0) stacks.remove(stacks.size() - 1);
        return v;
    }

那进阶的问题这么处理呢?
这个问题确实有点难度。实现起来也比较麻烦,因为整个系统看起来应该像一个“翻转”系统。如果我从堆栈1中弹出一个元素,那么我们需要将堆栈2底部的元素压到堆栈1的顶端。堆栈3的元素要到堆栈2....
注:你可能会不同意我的说法。认为实现这个函数不需要“翻转”整个堆栈。系统中的每个堆栈并不需要都是满栈的,这样的话也可以省下很多的时间复杂度,特别是在堆栈非常大的时候。但是如果假设除了最后一个堆栈之外,所有的堆栈必须满栈的话,这样的方法就不行了。具体采用什么样的结构,你可以在面试时和面试官好好沟通然后决定。

class SetOfStacks
{
    ArrayList<Stack> stacks = new ArrayList<Stack>();
    public int capacity;  //容量
    public SetOfStacks(int capacity)
    {
        this.capacity = capacity;
    }

    public Stack getLastStack()
    {
        if (stacks.size() == 0) return null;
        return stacks.get(stacks.size() - 1);
    }

    public void push(int v) {
		Stack last = getLastStack();
		if (last != null && !last.isAtCapacity()) { // add to last stack
			last.push(v);
		} else { // must create new stack
			Stack stack = new Stack(capacity);
			stack.push(v);
			stacks.add(stack);
		}
	}
	
    public int pop()
    {
        Stack last = getLastStack();
        System.out.println(stacks.size());
        int v = last.pop();
        if (last.size == 0) stacks.remove(stacks.size() - 1);
        return v;
    }

    public int popAt(int index)
    {
        return leftShift(index, true);
    }

    public int leftShift(int index, boolean removeTop)
    {
        Stack stack = stacks.get(index);
        int removed_item;
        if (removeTop) removed_item = stack.pop();
        else removed_item = stack.removeBottom();
        if (stack.isEmpty())
        {
            stacks.remove(index);
        }
        else if (stacks.size() > index + 1)
        {
            int v = leftShift(index + 1, false);
            stack.push(v);
        }
        return removed_item;
    }
}

class Stack
{
    private int capacity;
    public Node top, bottom;
    public int size = 0;

    public Stack(int capacity)
    {
        this.capacity = capacity;
    }
    public boolean isAtCapacity()
    {
        return capacity == size;
    }

    public void join(Node above, Node below)
    {
        if (below != null) below.above = above;
        if (above != null) above.below = below;
    }

    public boolean push(int v)
    {
        if (size >= capacity) return false;
        size++;
        Node n = new Node(v);
        if (size == 1) bottom = n;
        join(n, top);
        top = n;
        return true;
    }

    public int pop()
    {
        Node t = top;
        top = top.below;
        size--;
        return t.value;
    }

    public boolean isEmpty()
    {
        return size == 0;
    }
    public int removeBottom()
    {
        Node b = bottom;
        bottom = bottom.above;
        if (bottom != null) bottom.below = null;
        size--;
        return b.value;
    }
}

--- EOF---


你可能感兴趣的:(Cracking the coding interview--Q3.3)